如果你回答stop(),那就要凉凉了,stop()很快就要被放弃掉了。
stop()方法相当于你在看电视想要关掉的时候,直接拔掉插头,当线程在运行着的时候,直接stop()的话,可能会导致
锁资源没有释放
,导致死锁
的现象。我们可以使用中断阻塞的方法来
中断线程
,相当于把电视暂停。
一、interrupt()设置中断标志
InterruptDemo.java
public class InterruptDemo {
static int i = 0;
public static void main(String[] args) {
System.out.println("begin");
Thread t1 = new Thread(new Runnable() {
@Override
public synchronized void run() {
while (true) {
i++;
System.out.println(i);
// Thread.interrupted() 清除中断标志位
//Thread.currentThread().isInterrupted() 不会清除中断标志位
if (Thread.currentThread().isInterrupted()) {
System.out.println("======");
if(i == 4){
break;
}
}
}
}
});
t1.start();
// 中断方法 不会中断线程t1,只会设置一个中断标志位 flag=true
t1.interrupt();
}
}
new Thread().interrupt(); // 不会中断线程,只会设置一个中断标志位 flag = true;
Thread.interrupted(); // 会清除中断标志位
Thread.currentThread().isInterrupted(); // 不会清楚中断标志位
Thread.java
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
private native void interrupt0();
interrupt()的底层源码是调用了native方法interrupt0(),源码有一个很重要的注释【 // Just to set the interrupt flag】,仅仅只是设置了中断标志
sleep()和wait()可以感应中断
public class InterruptDemo {
static int i = 0;
public static void main(String[] args) {
System.out.println("begin");
Thread t1 = new Thread(new Runnable() {
@Override
public synchronized void run() {
while (true) {
i++;
System.out.println(i);
// sleep 期间可以感知中断信号吗? 可以
try {
// sleep可以被中断 抛出中断异常:sleep interrupted, 清除中断标志位
Thread.sleep(50000);
// wait可以被中断 抛出中断异常:InterruptedException, 清除中断标志位
// wait(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//Thread.interrupted(); // 清除中断标志位
//Thread.currentThread().isInterrupted() 不会清除中断标志位
if (Thread.currentThread().isInterrupted()) {
System.out.println("======");
if(i == 4){
break;
}
}
}
}
});
t1.start();
// 中断方法 不会中断线程t1,只会设置一个中断标志位 flag=true
t1.interrupt();
}
}
sleep可以感应中断信号,立刻被唤醒,抛出中断异常:sleep interrupted,清除中断标志位
wait可以感应中断信号,立刻被唤醒,抛出中断异常:InterruptedException,清除中断标志位
运行结果截图:
二、LockSupport.park()阻塞线程
public class InterruptDemo {
static int i = 0;
public static void main(String[] args) {
System.out.println("begin");
Thread t1 = new Thread(new Runnable() {
@Override
public synchronized void run() {
while (true) {
i++;
System.out.println(i);
// park 可以被中断 ,不会清除中断标志位
LockSupport.park();
//Thread.interrupted(); // 清除中断标志位
//Thread.currentThread().isInterrupted() 不会清除中断标志位
if (Thread.currentThread().isInterrupted()) {
System.out.println("======");
if(i == 4){
break;
}
}
}
}
});
t1.start();
// t1.interrupt();
LockSupport.unpark(t1);
}
}
LockSupport.park可以感应中断信号,阻塞会被中断,但不会清除中断标志位。
LockSupport.park()底层设置(counter = 0)阻塞线程
LockSupport.unpark()底层设置(counter = 1)发放许可,唤醒线程一次
运行结果截图