和线程打断有关的是三个方法:
1.interrupt() --打断某个线程(设置标志位)
2.isInterrupted() --查询某个线程是否被打断过(查询标志位)
3.static interrupted() --查询当前线程是否被打断过,并重置打断标志
interrupt():比如说有一个线程T,T调用了interrupt()方法,严格的来说并不是把线程T给打断了,只是给他设置了一个中断标志位,比如说T原来的标志位为false,调用interrupt()方法就会把他的标志位设置为ture。注意:只是设置了一个标记。看到这个标记之后做什么处理,是我们自己来完成的。
isInterrupted():比如说有一个线程T、线程T调用了interrupt()方法之后把标志位设置为了ture。然后在调用isInterrupted()方法,查询T线程是否被打断过。就会返回ture。被打断过。
static interrupted():这个方法是一个静态方法。静态方法是不需要调用实例对象、线程对象的。直接类名加点就可以调用。
下面来看几个案例:
案例一:interrupt()和isInterrupted()
/**
* interrupt()和isInterrupted()
* 设置标志位 + 查询标志位
*/
public class Demo01 {
public static void main(String[] args) throws InterruptedException {
//创建线程 t
Thread t = new Thread(()->{
for(;;){
//判断线程t是否被打断过 如果有被打断,做对应的处理,打印下面的语句
if(Thread.currentThread().isInterrupted()){
System.out.println("Thread is interrupted!");
System.out.println(Thread.currentThread().isInterrupted());
break;//结束循环
}
}
});
//线程t 开始执行
t.start();
//休眠5秒
Thread.sleep(5000);
//给线程t设置标志位
t.interrupt();
}
}
案例二:interrupt()和static interrupted()
/**
* interrupt()+static interrupted()
*/
public class Demo02 {
public static void main(String[] args) throws InterruptedException {
//创建线程t
Thread t = new Thread(()->{
//无限循环
for(;;){
//查看当前线程是否设置过标志位,设置过返回ture,没有设置过返回false,并重置当前线程的标志位
if(Thread.interrupted()){
System.out.println("Thread is interrupt!");
System.out.println(Thread.interrupted());
}
}
});
//开启线程
t.start();
//休眠5秒
Thread.sleep(5000);
//给线程t设置标志位
t.interrupt();
}
}
案例三:interrupt()和sleep()
/**
* interrupt和sleep()
*/
public class Demo03 {
static Object o = new Object();
public static void main(String[] args) throws InterruptedException {
//创建线程t
Thread t = new Thread(()->{
try {
//休眠10秒 再休眠的过程中,如果调用了interrupt()方法,会抛出InterruptedException异常。如何处理在于人为。
//wait()和join()方法也会抛出InterruptedException异常,和sleep()方法一样
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("Thread is interrupt!");
//一但catch住了异常,java会默认把标志复位,变为false,所以这里打印false
System.out.println(Thread.currentThread().isInterrupted());
}
});
//开启线程
t.start();
//休眠2秒
Thread.sleep(2000);
//给线程t设置标志位
t.interrupt();
}
}
案例四:interrupt()和synchronized
/**
* interrupt和synchronized
*/
public class Demo04 {
static Object o = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
synchronized (o){
try {
//休眠10秒
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
Thread.sleep(1000);//休眠1秒,确保t1已经启动
Thread t2 = new Thread(()->{
synchronized (o){
}
System.out.println("t2 end!!!");
});
t2.start();
//t2正在争抢锁的是否是否可以被打断?
t2.interrupt();
/**
* 结论:interrupt是不会打断线程的,注意:ta只是设置标志位,只是设置标志位,只是设置标志位!!!总要的事情说三遍
*/
}
}
案例五:
/**
* interrupt和ReentrantLock
*/
public class Demo05 {
static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(()->{
lock.lock();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
});
t1.start();
Thread.sleep(1000);
Thread t2 = new Thread(()->{
System.out.println("t2 start!");
try {
lock.lockInterruptibly();
System.out.println("t2抢到锁!!!");//可以看到没有打印这句话,说明t2没有抢到锁
lock.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t2 end!!!");
});
t2.start();
t2.interrupt();
/**
* 结论:如果想让interrupt()方法干扰抢锁的过程,需要用ReentrantLock上锁,在锁中调用lockInterruptibly()方法上锁,抛出InterruptedException重置标志位!
*/
}
}