//Thread.java
public void interrupt() //t.interrupt() 打断t线程(设置t线程某给标志位f=true,并不是打断线程的运行)
public boolean isInterrupted() //t.isInterrupted() 查询打断标志位是否被设置(是不是曾经被打断过)
public static boolean interrupted() //Thread.interrupted() 查看“当前”线程是否被打断,如果被打断,恢复标志位( 自动设回false )
【总结】:
interrupt—————设标志位。
isInterrupted———查标志位。
interrupted————查标志位 并 重置。
/**
* interrupt()与isInterrupted()
* 设置标志位 + 查询标志位
*/
public class T05_Interrupt_and_isInterrupted {
public static void main(String[] args) {
Thread t = new Thread(() -> {
for (; ; ) {
if (Thread.currentThread().isInterrupted()) {
System.out.println("Thread is interrupted!");
System.out.println(Thread.currentThread().isInterrupted());
break;
}
}
});
t.start();
SleepHelper.sleepSeconds(2);
t.interrupt(); //两秒钟之后设置中断标志位。
}
}
【最终输出】:
【线程结束的方案】:
我这个线程里面会隔一段儿时间 , 我就去检查一下有没有设置过我的标志位,如果被设置了,那么,我就可以让线程结束。
/**
* interrupt与interrupted()
*/
public class T06_Interrupt_and_interrupted {
public static void main(String[] args) {
Thread t = new Thread(() -> {
for (; ; ) {
if (Thread.interrupted()) {
System.out.println("Thread is interrupted!");
System.out.println(Thread.interrupted());
}
}
});
t.start();
SleepHelper.sleepSeconds(2);
t.interrupt();
//思考一下,如果在这里写
System.out.println("main: " + t.interrupted()); //在这里访问的时候,当前线程是主线程 Main。
//interrupted这个方法是静态成员变量,永远拿的都是当前线程。
//输出的是哪个线程的中断状态
}
}
/**
* interrupt与sleep() wait() join()
*/
public class T07_Interrupt_and_sleep {
public static void main(String[] args) {
Thread t = new Thread(() -> {
try {
Thread.sleep(10000); // 用interrupt打断这三个( sleep、wait、join )的话——会抛出异常( InterruptedException )
//你必须对异常进行处理。
} catch (InterruptedException e) { //只要catch , 它就会进行复位。
//一旦抛出InterruptedException异常 , Java会自动帮你把标志位进行复位。
System.out.println("Thread is interrupted!");
System.out.println(Thread.currentThread().isInterrupted());
}
});
t.start();
SleepHelper.sleepSeconds(5);
t.interrupt(); //设中断标志位的时候,这个线程正在sleep 。
}
}
【最终输出】:
/**
* interrupt与sleep() wait() join()
*/
public class T08_Interrupt_and_wait {
private static Object o = new Object();
public static void main(String[] args) {
Thread t = new Thread(() -> {
synchronized (o) {
try {
o.wait();
} catch (InterruptedException e) {
System.out.println("Thread is interrupted!");
System.out.println(Thread.currentThread().isInterrupted());
}
}
});
t.start();
SleepHelper.sleepSeconds(5);
t.interrupt();
}
}
【最终输出】:
设置标志位,这一件事情,能否把正在竞争锁的状态给打断?——不会的,不再在这个时候抛异常。
/**
* interrupt与sleep() wait() join()
*/
public class T09_Interrupt_and_sync {
private static Object o = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
synchronized (o) { //拿到这把锁~ ~ ~ ! ! !
SleepHelper.sleepSeconds(10); // 10秒内 这把锁归 t1 所有。
}
});
t1.start();
SleepHelper.sleepSeconds(1); //主线程1秒之后启动 t2。
Thread t2 = new Thread(() -> {
synchronized (o) {
//抢锁。
}
System.out.println("t2 end!");
});
t2.start();
SleepHelper.sleepSeconds(1);
t2.interrupt();
}
}
【最终结果】:
依然是在8秒之后,打印下图内容( 不会抛异常,也不会干别的 ):
总而言之,锁竞争的过程是不会被interrupt干扰的。
import java.util.concurrent.locks.ReentrantLock;
/**
* interrupt与sleep() wait() join()
*/
public class T10_Interrupt_and_lock {
private static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
lock.lock();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
System.out.println("t1 end!");
});
t1.start();
SleepHelper.sleepSeconds(1);
Thread t2 = new Thread(() -> {
lock.lock();
try {
} finally {
lock.unlock();
}
System.out.println("t2 end!");
});
t2.start();
SleepHelper.sleepSeconds(1);
t2.interrupt();
}
}
【最终输出】:
等待十秒左右,输出下图内容:
【总结】:
如果有一个线程占有了一把锁,并且老是不释放。另外一个线程去申请这把锁的时候,中间过程是干扰不到的。如果想干扰到的话,就要了解synchronized和ReentrantLock的区别了。
如果你想打断一个锁争抢的过程,那么就用——ReentrantLock。
import java.util.concurrent.locks.ReentrantLock;
/**
* interrupt与lockInterruptibly()
*/
public class T11_Interrupt_and_lockInterruptibly {
private static ReentrantLock lock = new ReentrantLock();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
lock.lock();
try {
SleepHelper.sleepSeconds(10);
} finally {
lock.unlock();
}
System.out.println("t1 end!");
});
t1.start();
SleepHelper.sleepSeconds(1);
Thread t2 = new Thread(() -> {
System.out.println("t2 start!");
try {
lock.lockInterruptibly(); //允许interrupt去干扰抢锁过程。
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
System.out.println("t2 end!");
});
t2.start();
SleepHelper.sleepSeconds(1);
t2.interrupt();
}
}
【最终输出】:
sleep()方法在睡眠的时候,不到时间是没有办法叫醒的,这个时候可以用interrupt设置标志位,然后呢必须得catch InterruptedException来进行处理,决定继续睡或者是别的逻辑,(自动进行中断标志复位)