Chinaunix首页 | 论坛 | 博客
  • 博客访问: 80502
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 340
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-02 20:25
文章分类

全部博文(31)

文章存档

2015年(2)

2014年(29)

我的朋友

分类: Java

2014-09-02 16:23:18

   Java之前有stop跟suspend方法从外部强制终止跟暂停一个线程。但是这两个方法都存在一个相当严重的问题,因为这样它们都被废弃了。
stop:一个线程被外部强行stop后会解锁所有监视器,导致阻塞该监视器的线程被唤醒。这可能导致被唤醒的线程使用一些状态不完全的对象。因为这些对象本来可能是要在被终止线程进行初始化等操作的。
suspend:该方法能够从外部强行暂停一个线程,但它不会也不应该释放锁,从而可能导致死锁。

  随着这两个方法被废弃,Java提供了中断策略来终止一个线程。也就是外部线程可以对目标线程给出一个中断信号,至于如何处理中断交由线程自己决定。所以每一个线程对象都可假想有一个线程中断标志位,中断一般涉及到3个方法:
1. interrupt:该方法设置线程的中断标志位为true。但是它会引发线程调度吗,需要确定?  线程的wait,sleep,join会捕获该状态,抛出InterruptException。
2. isInterrupted:检查线程对象的中断标志
3. interrupted:这是个静态方法,作用同isInterrupted,区别是将中断标志设为false
4. InterruptException:有wait,sleep,join等可中断方法在中断标志位true时抛出,线程捕获该异常后,中断标志自动设为false.
 有了上诉方法:可以这样中断一个线程:

点击(此处)折叠或打开

  1. class ThreadA extends Thread{
  2.         public void run(){
  3.             while(!Thread.currentThread().isInterrupted()){
  4.                 try{
  5.                     Thread.sleep(10000); //类似于sleep的可中断方法,如wait等
  6.                 }catch(InterruptedException e){
  7.                     Thread.currentThread().interrupt();
  8.                 }
  9.             }
  10.         }
  11.     }
  但是这个方法不通用,因为很多线程不会调用阻塞方法,也有些线程调用的是不可中断的阻塞方法。那么上诉方法就失效了。

一. 没有调用阻塞方法的线程

   对于这种情况,通常外部线程是没办法终止该线程了。像以下这种方法:

点击(此处)折叠或打开

  1. public void run(){
  2.    while(!Thread.currentThread().isInterrupted() && need more work to do){
  3.           ...
  4.    }
  5. }
  该方法问题是调用interrupt时,我们不知道目标线程的状态,不知道它执行到哪里。

二. 不可中断阻塞

  一些线程在不可中断的方法阻塞,比如不可中断IO,等待锁等。那么它无法响应中断信号,因为这些阻塞方法不会抛出InterruptException。一个方法捕获这些不可中断IO能抛出的异常,然后显示产生这些异常。比如输入流in.read属于不可中断阻塞,但在read过程中如果in被close则会抛出异常,那么改写interrupt让其调用close是个办法。
 对于阻塞于锁对象,synchronized并不支持响应中断。java并发包的lock提供了可中断锁。
阅读(860) | 评论(0) | 转发(0) |
0

上一篇:2. 分离锁

下一篇:5. ThreadLocal

给主人留下些什么吧!~~