中断为什么能结束线程
来源:互联网 发布:傻瓜电子杂志制作软件 编辑:程序博客网 时间:2024/04/30 23:16
一个常用但但并不一定能中断线程方法(因为如果此线程阻塞,则前面的判断可能会永远执行不到)
package seven;import java.math.BigInteger;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;import common.Utils;public class PrimeProducer extends Thread { final BlockingQueue<BigInteger> queue; private volatile boolean cancelled = false; public PrimeProducer(BlockingQueue queue) {this.queue = queue; } @Override public void run() {BigInteger p = BigInteger.ONE;/** * 分析下面循环的执行过程 当线程执行时,检测当前线程的cancelled标志,如果没有被设置true,那么执行 queue.put方法 * 此方法有可能导入线程阻塞,如果我们上面循环条件用 !cancelled进行判断的话,当消费者 * 要求阻塞生产者线程时,会判断canceled状态,而当前生产者处于阻塞状态,无法无法进行 * cancelled值的比较,而消费者可能不再消费,此时queue一直处于满的状态,会一直阻塞, 所以当前的停止线程并不适用 */while (!cancelled) { try {queue.put(p = p.nextProbablePrime());System.out.println(Thread.currentThread().getName() + " 生产数字 "+ p); } catch (InterruptedException e) {System.out.println(Thread.currentThread().getName() + " 线程中断"); }} } public void cancel() {this.cancelled = true; } public static void main(String args[]) {BlockingQueue<BigInteger> queue = new ArrayBlockingQueue<BigInteger>(3);PrimeProducer producer = new PrimeProducer(queue);producer.start();for (;;) { try {System.out.println(Thread.currentThread().getName() + "消费数据 "+ queue.take()); // 从队列取出一个数Utils.sleep(1); // 停止1s,显示出消费速度慢于生产速度 producer.cancel(); // 消费者请求停止生产 break; // 消费者停止消费 } catch (InterruptedException e) {System.out.println("被中断了"); }} }}
线程将不会停止,而是一直阻塞到这个地方
下面是一个改进的例子,用中断来进行线程的停止,因为,在线程阻塞状态下,中断会引起线程抛出一个 InterruptedException 而且设置中断标志位,这样,在线程阻塞的时候
我们也可以照样将线程停止;只是有一点要注意,在线程阻塞处理中断时,会抛出一个异常,而且设置中断标志位,线程由waitingQueue 进入到 Runnable Queue,
等待JVM的再次调度,再次调试时,就是从 catch捕获的地方开始执行了
为什么要将 while 写在了循环之中,而不是写在 try 之外?
当线程中 put 处于阻塞状态时,我们不能利用前面的那个例子进行线程停止,我们是利用的线程中断,主线程向 这个线程发送了
一个中断请求,而这个线程在阻塞状态收到一个中断请求会产生一个InterruptedException,然后将 中断标记置为 false(也就是清空
中断标记),如果线程不处于阻塞状态收到了一个中断请求,那么线程的中断标志位会被置为 trur,也就是这一点,让我们把循环写在了 catch 中的,如果线程不处于阻塞
,收到一个抗洪请求后,中断标志为 true,这样循环的条件就不满足,线程会停止,而线程处于阻塞状态时,收到一个抗洪请求时,抗洪标记会被清除,那么
如果循环在 catch 外的话,执行完catch 还会在执行循环,因此,只能利用catch跳出循环,而结束线程
package seven;import java.math.BigInteger;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;import common.Utils;public class PrimeProducerStop extends Thread { final BlockingQueue<BigInteger> queue; private volatile boolean cancelled = false; public PrimeProducerStop(BlockingQueue queue) {this.queue = queue; } /** * 解析下面的这段代码: * 为什么要将 while 写在了循环之中,而不是写在 try 之外? 当线程中 put 处于阻塞状态时,我们不能利用前面的那个例子进行线程停止,我们是利用的线程中断,主线程向 这个线程发送了 一个中断请求,而这个线程在阻塞状态收到一个中断请求会产生一个InterruptedException,然后将 中断标记置为 false(也就是清空 中断标记),如果线程不处于阻塞状态收到了一个中断请求,那么线程的中断标志位会被置为 trur,也就是这一点,让我们把循环写在了 catch 中的,如果线程不处于阻塞 ,收到一个抗洪请求后,中断标志为 true,这样循环的条件就不满足,线程会停止,而线程处于阻塞状态时,收到一个抗洪请求时,抗洪标记会被清除,那么 如果循环在 catch 外的话,执行完catch 还会在执行循环,因此,只能利用catch跳出循环,而结束线程 */ @Override public void run() {BigInteger p = BigInteger.ONE;try { while (!Thread.currentThread().isInterrupted()) {//为什么要将循环写在 try{}之中,而不是之外?queue.put(p = p.nextProbablePrime()); System.out.println(Thread.currentThread().getName() + " 生产数字 " + p); }} catch (InterruptedException e) {//让catch 直接跳出循环,这样就起到了停止线程的作用 System.out.println(Thread.currentThread().getName() + " 线程中断"); System.out.println(Thread.currentThread().isInterrupted());}System.out.println(Thread.currentThread().getName() + " is over"); } public void cancel() {interrupt(); } public static void main(String args[]) {BlockingQueue<BigInteger> queue = new ArrayBlockingQueue<BigInteger>(3);PrimeProducerStop producer = new PrimeProducerStop(queue);producer.start();for (;;) { try {System.out.println(Thread.currentThread().getName() + "消费数据 "+ queue.take()); // 从队列取出一个数Utils.sleep(1); // 停止1s,显示出消费速度慢于生产速度 producer.cancel(); // 消费者请求停止生产 break; // 消费者停止消费 } catch (InterruptedException e) {System.out.println("被中断了"); }} }}
- 中断为什么能结束线程
- Interrupt中断结束线程
- java中断和线程结束深入探讨
- 为什么要中断线程呢?
- pthread_cancel() 能结束哪些线程-linux
- 为什么“-1”能作为判断文本文件结束的标志然而为什么不能作为二进制文件是否结束的标志?
- 线程结束
- 结束线程
- 为什么添加ACL访问控制列表以后,进程还是能被结束 (dump acl )
- android(java)里面完全中断(结束)一个正在运(执)行的线程
- 线程中断
- 中断线程
- 中断线程
- 中断线程
- 中断线程
- 线程中断
- 中断线程
- 线程中断
- 在VC工程中添加多语言支持 (资源DLL)
- 备份恢复IIS的设置
- 'Detailed' checkbox in Material Workbench
- jQuery插件autocomplete应用详解
- VS2010 编译运行 OCILIB 示例工程
- 中断为什么能结束线程
- Arcengine编辑要素属性
- 嵌入式数据结构设计
- RHEL6.1编译内核-kernel-3.0.4
- myeclipse启动提醒问题
- VC++6.0 类查看信息不可访问
- Android 监听EditText输入文字的字数
- 可视门禁中的MVC模式
- 更强的链表klist