不正确的线程中止
Stop方法
中止线程,并且清除监控器锁的信息,但是可能导致线程安全问题,JDK不推荐使用
Destroy
JDK并没有实现该方法
代码示例
为什么不推荐使用stop呢?一段代码就能解答:
package com.study.hc.thread.chapter1.thread;
public class StopThread extends Thread {
private int i = 0, j = 0;
@Override
public void run() {
synchronized (this) {
// 增加同步锁,确保线程安全
++i;
try {
// 休眠10秒,模拟耗时操作
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
++j;
}
}
/** * 打印i和j */
public void print() {
System.out.println("i=" + i + " j=" + j);
}
}
执行代码:
package com.study.hc.thread;
public class Demo3 {
public static void main(String[] args) throws InterruptedException {
StopThread thread = new StopThread();
thread.start();//启动线程
Thread.sleep(1000);//主线程休眠1s,保证子线程的执行
thread.stop();//错误的中止
while(thread.isAlive()){
//确保线程已中止
}
//输出结果
thread.print();
}
}
问题分析
输出结果:
i=1 j=0
很明显该答案是不符合一致性的,问题主要就处在了当++i执行完成之后没等到thread.sleep(10000)结束就中止了线程,所以++i执行了而++j并没有执行。这样的话就破坏了数据的一致性和代码的原子性
正确的终止
还是上面的代码,只需要做适当的修改即可。
package com.study.hc.thread;
public class Demo3 {
public static void main(String[] args) throws InterruptedException {
StopThread thread = new StopThread();
thread.start();//启动线程
Thread.sleep(1000);//主线程休眠1s,保证子线程的执行
//thread.stop();//错误的中止
thread.interrupt();//正确的终止
while(thread.isAlive()){
//确保线程已中止
}
//输出结果
thread.print();
}
}
interrupt
如果目标在调用Object的wait(),wait(long,int),join(),join(long,int)或者sleep(long,ing)等方法时被阻塞,那么interrupt就会生效,该线程的中断状态被清除,抛出InterruptedException异常。
如果目标是被I/O或者NIO的Channel所阻塞,同样,I/O操作会被中断或者返回异常值。达到中止线程的目的。
如果以上状态都不满足,则会设置线程为中断状态
通过标志位来实现对中止的控制
package com.study.hc.thread;
public class Demo4 {
public volatile static boolean flag = true;
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
try {
while (flag){
System.out.println("运行中");
Thread.sleep(1000L);
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
//3秒之后,将状态标志该为false,代表不继续运行。
Thread.sleep(3000L);
flag=false;
System.out.println("程序运行结束");
}
}
在该代码段中,加入了flag这个标志位,当它为true的时候,让程序正常运行,而当它为false的时候,则实现了中止。