近期看了一本关于多线程的书籍《Java多线程编程核心技术》。下面对学习到的关于线程的终止方法进行总结,如果有错误欢迎大家指出,如果对大家有帮助,欢迎转载和点赞。
java中有三中方法终止正在运行的线程:
(1)、通过推退出标志,使线程正常退出,也就是当run方法完成后终止。
(2)、通过Thead.stop()方法强行终止线程,但是不推荐这么使用,因为此方法是不安全的,已经作废过期。
(3)、调用interrupt方法终止线程。
调用stop方法后会马上终止正在运行的线程,这样强制终止线程,有可能会导致有些清理工作得不到完成,还有种情况是对锁定的数据进行了解锁,导致数据得不到同步处理,导致数据出现不一致。
下面以一个例子进行介绍。
package thread.stop;
/***
* 用于线程stop方法中断流程例子演示
* @author swh
*
*/
public class ThreadStopTest extends Thread {
public void run() {
int i = 0;
try {
while( true ) {
i++;
System.out.println(i);
Thread.sleep(1000L);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
try {
ThreadStopTest thread = new ThreadStopTest();
thread.start();
Thread.sleep(5000L);
thread.stop();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
上面的代码比较简单,及时在main 线程中启动一个ThreadStopTest线程,然后休眠5秒,ThreadStopTest线程就是循环输出i,输出一次后休眠一秒,当ThreadStopTest循环运行5次main线程醒来,通过stop方法强制中断线程。下面是运行的结果。
现在以一个简单的例子来介绍下用stop方法中断线程会导致的问题。
package thread.stop;
/***
* 用于演示线程stop方法会导致的安全问题
* @author swh
*
*/
public class SafeStopThread implements Runnable {
private int i =0;
@Override
public void run() {
synchronized("") {
i++;
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
i--;
System.out.println(Thread.currentThread().getName()+":"+i);
}
}
public static void main(String args[]) {
Thread thread=new Thread(new SafeStopThread());
thread.start();
for(int i =0;i<5;i++) {
new Thread(thread).start();
}
thread.stop();
}
}
其中i是几个线程公用的变量,其中run方法中加上了 synchronized 代码块,表示内部是原子逻辑,它会先自增然后再自减少,按照synchronized同步代码块的规 则来处理,此时无论启动多少个线程,打印出来的结果都应该是a=0,但是如果有一个正在执 行的线程被stop,就会破坏这种原子逻辑。下面是运行的结果。
interrupt方法并不像stop方法那样强制中断一个线程,而是给线程打上一个中断标志,并不是真的中断线程。这里先需要先介绍下两个方法。
interrupted();测试当前线程是否已经中断。此方法调用后会重置中断标志,即第一调用如果为true后会重置为false;
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
isinertrupted();测试线程是否已经中断。
public boolean isInterrupted() {
return isInterrupted(false);
}
调用interrupt中断线程例子如下,我们可以调用上面两个方法来得到中断标志来判断,来解决逻辑的原子性被破坏的问题;
package thread.interrupt;
/***
* 流程中断
* @author swh
*
*/
public class InertruptThread extends Thread {
public void run() {
int i = 0;
try {
while(!this.isInterrupted()) {
i++;
System.out.println(i);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
try {
InertruptThread inertruptThread = new InertruptThread();
inertruptThread.start();;
Thread.sleep(10L);
inertruptThread.interrupt();;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
运行后得结果: