您的位置:首页 > 编程语言 > Java开发

java多线程-interrupt

2015-12-02 11:20 579 查看
java中的interrupt(中断)很容易让人产生歧义,仅从字面意思上理解是如果一个Thread实例调用了interrupt方法会中断该线程。而事实并不是这样,该方法知识为我们提供了一种中断的协作机制,真正什么时候去中断线程需要我们自己去定义中断的逻辑。因为interrupt方法仅仅是为该线程设置了中断标志,并不会中断线程,我们可以利用该中断标志来中断该线程。

我们一般采用两种方式中断当前线程:

一种是利用阻塞方法sleep(),wait(),join(),这几个方法会抛出InterruptException,当我们在调用了该线程的interrupt()方法时会抛出中断异常,然后我们就可以设置合理的逻辑使线程线程中断(我觉得用尽快跳出run方法,使任务提前结束来表述更为贴切)。注意一点就是一旦产生了中断异常后,线程的中断标志就会被自动清除(中断状态从true变为false)

另外一种就是在任务中不断检测线程的中断标志来实现线程的中断,java为我们提供了两个获取中断标志的方法一个是Thread.interrupted()的静态方法,另一个是isInterrupted()的实例方法,这两个方法会返回线程的中断状态。

通过代码来说明上面两种中断方法。

<span style="font-size:14px;">package com.lql.thread3;

/**
* 通过阻塞方法抛出异常,当出现中断时阻塞方法产生一个中断异常
* 在异常处理中,采取合适的措施中断线程
* @author Administrator
*
*/
public class MyInterrupt implements Runnable{

private boolean flag = true;

@Override
public void run() {
// TODO Auto-generated method stub
while(flag){
System.out.println("hello,world!");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block

//产生中断异常,在处理中断异常时可以选择终止本线程

System.out.println("在阻塞的时候,检测到中断,会产生InterruptedException");

//异常产生后,线程的中断标志会被标志位false
//所以Thread.interrupted()会返回false
System.out.println("Thread.interrupted() " + Thread.interrupted());
System.out.println("Thread.currentThread().isInterrupted() " +Thread.currentThread().isInterrupted());

//在这里修改标志,将本线程终止,标志位被修改后,当前线程就会跳出循环任务,之后线程就会被中断
flag = false;
}
}
System.out.println(Thread.currentThread().getName() +"is stoped");
}

}</span>
<span style="font-size:14px;">package com.lql.thread3;

public class InterruptTest {

public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new MyInterrupt());
thread.start();

//主线程休眠100毫秒,让子线程可以执行一段时间
Thread.sleep(100);

//在主线程中调用子线程的interrupt()方法,置子线程的中断标志为true
//此时子线程的执行的sleep就会产生一个中断异常
thread.interrupt();
}
}</span>
运行结果

hello,world!
hello,world!
在阻塞的时候,检测到中断,会产生InterruptedException
Thread.interrupted() false
Thread.currentThread().isInterrupted() false
Thread-0is stoped


以上说明的是第一种中断子线程的方式,即在阻塞方法的异常处理中加入合适的逻辑中断线程

再来说明一下通过判断标志位状态的方式终止线程的方式

package com.lql.thread3;

public class MyInterrupt2 implements Runnable{

@Override
public void run() {
// TODO Auto-generated method stub
//通过不断检测线程的中断标志来判断是否中断当前线程的执行
while(!Thread.currentThread().isInterrupted()){
System.out.println("hello,world");
}
System.out.println(Thread.currentThread().getName()+ " is stop");
}

}
package com.lql.thread3;

public class InterruptTest {

public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new MyInterrupt2());
thread.start();

//主线程休眠1毫秒,让子线程可以执行一段时间
Thread.sleep(1);

thread.interrupt();
}
}
hello,world
hello,world
hello,world
hello,world
hello,world
Thread-0 is stop
</pre><p><span style="font-size:14px;">可以看到子线程运行一段时间后同样被中断中断了</span></p><p><span style="font-size:14px;"></span></p><p><span style="font-size:14px;">如果我们在子线程中加入一个阻塞方法比如sleep呢</span></p><p><span style="font-size:14px;"></span><pre name="code" class="java">package com.lql.thread3;

public class MyInterrupt2 implements Runnable{

@Override
public void run() {
// TODO Auto-generated method stub
//通过不断检测线程的中断标志来判断是否中断当前线程的
while(!Thread.currentThread().isInterrupted()){
System.out.println("hello,world");

try {
Thread.sleep(50);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
System.out.println(Thread.currentThread().getName()+ " is stop");
}

}


运行可以看到子线程会一致运行下去,因为主线程中调用子线程的interrupt()方法会使子线程的sleep方法产生一个中断异常,进而使该线程的中断标志清除(即中断标志变为false)。所以子线程会一直运行下去。


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: