此系列文章是参考《JAVA并发编程从入门到精通》一书写的一些读后笔记,其中也会进行扩展补充,写的不准确的地方还望广大同胞指出,大家一起学习,一起码奴。
Java线程中断的几种方法
- Thread.stop()
该方法强迫停止一个线程,并跑出一个新创建的ThreadDeath,源码如下
public final void stop() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
checkAccess();
if (this != Thread.currentThread()) {
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
if (threadStatus != 0) {
//如果线程被挂起则唤醒线程
resume(); // Wake up thread if it was suspended; no-op otherwise
}
// The VM can handle all thread states
//stop0()是一个native方法
stop0(new ThreadDeath());
}
- Thread.interrupt()
Java的中断机制是一种协作机制,也就是通过调用中断方法不能直接终止另一个线程,而需要被中断的线程自己处理中断。例如:当线程t1想中断线程t2,只需要在线程t1中将线程t2对象的中断标识设置为true,然后线程2可以选择在合适的时候处理该中断请求。Thread类中提供了三个关于中断的方法,如下:
- public static boolean interrupted():测试当前线程是否已经中断,线程的中断状态由该方法清除,也就是说连续两次调用该方法,则第二次调用则返回false。
- public boolean isInterrupted():测试线程是否已经中断,线程的中断状态不受该方法的影响
- public void interrupt():中断线程,但是没有返回结果,是唯一能将中断状态设置为true的方法
看过了关于线程中断的相关方法,那么再来看下他们是如何被使用的。上面的例子中,线程t1通过调用interrupt方法将线程t2的中断状态设置为true,t2可以在合适的时候调用interrupted或isInterrupted来检测状态并做相应的处理
测试代码如下:
//测试线程类,使用while保证线程一直运行,通过Thead.isInterrupted()方法来判断中断状态
public class ThreadInterrupt implements Runnable{
@Override
public void run() {
boolean stop = false;
while (!stop){
System.out.println("ThreadInterrupt is running");
long time = System.currentTimeMillis();
while ((System.currentTimeMillis() - time < 1000)){
//为了减少打印次数
}
if(Thread.currentThread().isInterrupted()){
System.out.println("ThreadInterrupt is interrupted");
//需要线程本身去处理一下它的终止状态
break;
}
}
System.out.println("ThreadInterrupt is exit");
}
}
//测试方法
public static void main(String[] args) throws Exception{
Thread thread = new Thread(new ThreadInterrupt(),"ThreadInterrupt");
System.out.println("start thread");
//启动线程ThreadInterrupt,并等待3s
thread.start();
Thread.sleep(3000L);
System.out.println("Interrupting thread....");
thread.interrupt();
System.out.println("线程是否中断:" + thread.isInterrupted());
Thread.sleep(3000l);
System.out.println("stop thread");
}
运行结果如下:
start thread
ThreadInterrupt is running
ThreadInterrupt is running
ThreadInterrupt is running
ThreadInterrupt is running
Interrupting thread....
线程是否中断:true
ThreadInterrupt is interrupted
ThreadInterrupt is exit
stop thread
从运行结果可以看出,因为测试的main方法中调用了中断方法,而ThreadInterrupt也处理了该中断请求,所以ThreadInterrupt线程真正的终止了。
上面演示了interrupt使线程中断的一种方式,实际上java的中断机制还可以处理一些更为复杂的逻辑。当外部线程对某线程调用了Thread.interrupt(),如果线程处在可以中断状态下(调用了sleep或者wait等特定会发生阻塞的方法),那么该线程会立即被唤醒,同时如果是阻塞在IO上,对应的资源会关闭。如果该线程接下来不执行Thead.Interrupted()方法,那么该线程处理任何IO资源的时候,都会导致这些资源关闭。测试代码如下:
//将上面demo的run方法更改下,重新进行测试
@Override
public void run() {
boolean stop = false;
while (!stop){
System.out.println("ThreadInterrupt is running");
try{
Thread.sleep(300l);
}catch (InterruptedException ex){
// 1、使线程继续运行
// Thread.currentThread().interrupted();
// 2、终止线程
break;
}
}
System.out.println("ThreadInterrupt is exit");
}
如上方式,线程ThreadInterrupt依旧会被中断。但需要注意的是一定要对isInterrupted状态进行处理,否则代码如果是死循环的话,线程永远不会结束。