Thread包含interrupt()方法,因此你可以终止被阻塞的任务,这个方法将设置线程的中断状态。如果一个线程已经被阻塞,或者试图执行一个阻塞操作。那么设置这个线程的中断状态将

抛出InterruptedException。当抛出改异常或者该任务调用Thread.interrupted()时,中断状态将被复位。

  查看Thread的API,关于中断的方法有:

  void interrupt()   interrupts this thread

  static boolean interrupted()  Test whether the current thread has been interrupted

  boolean isInterrupted()  Test whether the current thread has been interrupted

  通过几个例子看一下中断的用法和特点:

  例子一,分别模拟了,中断线程sleep,I/O和synchronized修饰的方法。结论:调用interrupt()方法,只有sleep的线程可以被中断,I/O和用synchronized修饰的线程是不能被中断的

public class Interrupting {
private static ExecutorService service = Executors.newCachedThreadPool(); static void test(Runnable r) throws InterruptedException{
Future<?> f = service.submit(r);
TimeUnit.MILLISECONDS.sleep(100);
System.out.println("Interrupting: " + r.getClass().getName());
f.cancel(true); //interrupts if running
System.out.println("interrupted send to: " + r.getClass().getName()); }
public static void main(String[] args) throws Exception{
// test(new SleepBlocked());
// test(new IOBlocked(System.in));
test(new SynchronizedBlocked());
TimeUnit.SECONDS.sleep(10);
System.out.println("Aborting with System.exit(0)");
System.exit(0);
}
} class SleepBlocked implements Runnable {
@Override
public void run() {
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
System.out.println("InterruptedException");
}
System.out.println("Exiting SleepBlocked.run()");
}
} class IOBlocked implements Runnable {
private InputStream is; public IOBlocked(InputStream is) {
this.is = is;
} @Override
public void run() {
try {
System.out.print("waiting for read:");
is.read();
} catch (IOException e) {
if(Thread.currentThread().isInterrupted()) {
System.out.println("Interrupted IO Blocked");
} else {
throw new RuntimeException(e);
}
}
System.out.println("Exiting IOBlocked.run()");
}
} class SynchronizedBlocked implements Runnable {
public SynchronizedBlocked() {
new Thread(){
@Override
public void run() {
f();
}
}.start();
} public synchronized void f() {
while(true) { //Never release lock
Thread.yield();
}
}
@Override
public void run() {
System.out.println("try to call f()");
f();
System.out.println("Exiting SynchronizedBlocked.run()");
}
}

  例子二,sleep是可以被中断的,中断后,中断标识位“复位”

package org.burning.sport.javase.thread.interrupt;

import java.util.concurrent.TimeUnit;

public class InterruptSleep implements Runnable{
@Override
public void run() {
try {
while (true) {
System.out.println("开始睡了");
TimeUnit.SECONDS.sleep(3);
}
} catch (InterruptedException e) {
boolean isInterrupt = Thread.interrupted();
//中断状态被复位
System.out.println("中断状态:" + isInterrupt);
}
} public static void main(String[] args) throws Exception{
Thread t = new Thread(new InterruptSleep());
t.start();
TimeUnit.SECONDS.sleep(5);
t.interrupt();
System.out.println("interrupted is: " + t.isInterrupted());
} }
/*
开始睡了
开始睡了
interrupted is: false
中断状态:false
*/

  例子三,普通方法是中断不了的,并且从最后的输出结果 interrupted is: true 看出中断标识位没有被清除。

package org.burning.sport.javase.thread.interrupt;

import java.util.concurrent.TimeUnit;

public class InterruptCommonTest implements Runnable{
@Override
public void run() {
while (true) {
System.out.println("你中断一个试试");
boolean interrupt = Thread.interrupted();
System.out.println("中断状态" + interrupt);
}
} public static void main(String[] args) throws Exception{
Thread t = new Thread(new InterruptCommonTest());
t.setDaemon(true);
t.start();
TimeUnit.SECONDS.sleep(5);
t.interrupt();
System.out.println("interrupted is: " + t.isInterrupted());
}
}
/*
中断状态false
你中断一个试试
中断状态false
你中断一个试试
中断状态false
interrupted is: true
你中断一个试试
中断状态false
*/

  总结:你能够中断对sleep的调用(或者任何要求抛出InterruptedException的调用)。但是你不能中断正在试图获取synchronized锁或者正在试图执行IO操作的线程

  例子四:Lock与中断的关系。

   上面的例子中看到,synchronized是不能被中断的,但是Lock是可以被中断的。这个算是synchronized和Lock的不同点。查看Lock的API,有一个方法

   void lockInterruptibly() throws InrruptedException 就是可以被中断的方式来获取锁的方法。

package org.burning.sport.javase.thread.interrupt;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock; public class InterruptLockTest implements Runnable{
private static ReentrantLock lock = new ReentrantLock(); @Override
public void run() {
try {
lock.lockInterruptibly();
while(true) {
Thread.yield();
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
} } public static void main(String[] args) throws Exception{
InterruptLockTest lockTest = new InterruptLockTest();
Thread t1 = new Thread(lockTest);
Thread t2 = new Thread(lockTest);
t1.start();
t2.start();
TimeUnit.SECONDS.sleep(3);
t2.interrupt();
System.out.println("结束...");
}
}
/*
结束...
java.lang.InterruptedException
at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222)
at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335)
at org.burning.sport.javase.thread.interrupt.InterruptLockTest.run(InterruptLockTest.java:18)
at java.lang.Thread.run(Thread.java:745)
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261)
at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457)
at org.burning.sport.javase.thread.interrupt.InterruptLockTest.run(InterruptLockTest.java:25)
at java.lang.Thread.run(Thread.java:745)
*/

  

https://gitee.com/play-happy/base-project

参考:

  【1】《Think in Java》,21.3.4 中断

  【2】《Java 高并发程序设计》,2.2.3 线程中断

线程的中断(Lock与synchronized)的更多相关文章

  1. (转)Lock和synchronized比较详解

    今天看了并发实践这本书的ReentantLock这章,感觉对ReentantLock还是不够熟悉,有许多疑问,所有在网上找了很多文章看了一下,总体说的不够详细,重点和焦点问题没有谈到,但这篇文章相当不 ...

  2. Lock较synchronized多出的特性

    1.尝试非阻塞形式获取锁 tryLock() :当前线程尝试获取锁,如果锁被占用返回false;如果成功则占有锁 //类似用法if(lock.tryLock()) { try { System.out ...

  3. Lock和synchronized的区别和使用

    Java并发编程:Lock 今天看了并发实践这本书的ReentantLock这章,感觉对ReentantLock还是不够熟悉,有许多疑问,所有在网上找了很多文章看了一下,总体说的不够详细,重点和焦点问 ...

  4. synchronized和lock以及synchronized和volatile的区别

    synchronized和volatile区别synochronizd和volatile关键字区别: 1. volatile关键字解决的是变量在多个线程之间的可见性:而sychronized关键字解决 ...

  5. java多线程关键字volatile、lock、synchronized

    --------------------- 本文来自 旭日Follow_24 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/xuri24/article/detail ...

  6. Lock、synchronized和ReadWriteLock,StampedLock戳锁的区别和联系以及Condition

    https://www.cnblogs.com/RunForLove/p/5543545.html 先来看一段代码,实现如下打印效果: 1 2 A 3 4 B 5 6 C 7 8 D 9 10 E 1 ...

  7. Java并发编程:Lock和Synchronized <转>

    在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方 ...

  8. Lock 和 synchronized 的区别

    Lock 和 synchronized 的区别 Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现: synchronized在发生异常时,会 ...

  9. 002 Lock和synchronized的区别和使用

    转自 https://www.cnblogs.com/baizhanshi/p/6419268.html 今天看了并发实践这本书的ReentantLock这章,感觉对ReentantLock还是不够熟 ...

随机推荐

  1. 762. Prime Number of Set Bits in Binary Representation二进制中有质数个1的数量

    [抄题]: Given two integers L and R, find the count of numbers in the range [L, R] (inclusive) having a ...

  2. UNION 和 UNION ALL 操作符

    SQL UNION 操作符 1.UNION 操作符用于合并两个或多个 SELECT 语句的结果集. 请注意:UNION 内部的 SELECT 语句必须拥有相同数量的列.列也必须拥有相似的数据类型.同时 ...

  3. Linux anaconda 内网 安装 卸载

    安装并不难, 官网介绍的很清楚, 但每次到官网找安装方法不方便,我总结了本文(很全) 官网下载Linux版anaconda, 地址https://www.anaconda.com/download/# ...

  4. 基于UML的中职班主任工作管理系统的分析与设计--文献随笔(二)

    一.基本信息 标题:基于UML的中职班主任工作管理系统的分析与设计 时间:2016 出版源:遵义航天工业学校 关键字:中职学校; 班主任工作管理; UML建模 二.研究背景 问题定义:班主任是一项特殊 ...

  5. Python3实战系列之五(获取印度售后数据项目)

    问题:续接上一篇.说干咱就干呀,勤勤恳恳写程序呀! 目标:此篇我们试着把python程序打包成.exe程序.这样就可以在服务器上运行了.实现首篇计划列表功能模块的第二步: 2.将python程序转为 ...

  6. 学习Acegi应用到实际项目中(1)

    在此,本人声明,我处于菜鸟阶段,文章的内容大部分摘自zhanjia的博客(http://zhanjia.iteye.com/category/43399),旨在学习,有很多地方,我理解不够透彻,可能存 ...

  7. centos7配置Hadoop集群环境

    参考: https://blog.csdn.net/pucao_cug/article/details/71698903 设置免密登陆后,必须重启ssh服务 systermctl restart ss ...

  8. js- DOM事件之按钮绑定函数注意事项

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8&qu ...

  9. uniGUI动态建立Form及释放

    uniGUI动态建立Form及释放 (2015-10-01 14:51:12) 转载▼   分类: uniGUI 用uniGUI开发的项目中,难免要遇到动态建立一个Form,再释放掉,与传统Delph ...

  10. Centos系统安装InfluxDB

    概述安装influxDB时需要root用户或者管理员权限. 端口默认情况下,InfluxDB会使用如下的端口: * TCP8086端口是服务器监听端口,对HTTP API响应 * TCP8088端口是 ...