java没有提供任何机制来安全的终止线程(Thread.stop Thread.suspend存在严重缺陷),提供了中断,一种写作机制,能够使一个线程终止另一个线程的当前工作。
任务取消:
如果外部代码能在某个操作正常完成之前将其置入“完成”状态,那么就是可取消的(cancellable)
取消策略:
一个可取消的任务必须拥有取消策略。
how 其他代码如何请求取消该任务
when 任务在何时检查是否已经请求了取消
what 响应取消请求应该执行哪些操作
一种简单的取消策略:
public class PrimeGenerator implements Runnable{
private final List<BigInteger> primes=new ArrayList<BigInteger>();
private volatile boolean cancelled;
public void run(){
BigInteger pBigInteger=BigInteger.ONE;// 为1
while(!cancelled){
pBigInteger=pBigInteger.nextProbablePrime();
synchronized (this) {
primes.add(pBigInteger);
}
}
}
public void cancel(){cancelled=true;}
public synchronized List<BigInteger> get(){
return new ArrayList<BigInteger>(primes);
}
}
定义取消标志位 volatile boolean cancelled
定义取消方法 void cancell()
在run()方法中合适位置检查标志位,有无被其他线程置true
缺点:在检查取消标志之前,存在阻塞的方法,可能永远都不会检查这个标志位
中断取消:
public class primeProducer extends Thread{
private final BlockingQueue<BigInteger> queue;
public primeProducer(BlockingQueue<BigInteger> queue) {
// TODO Auto-generated constructor stub
this.queue=queue;
}
public void run(){
try{
BigInteger pBigInteger=BigInteger.ONE;
while(!Thread.currentThread().isInterrupted())
queue.put(pBigInteger=pBigInteger.nextProbablePrime());
}
catch(InterruptedException consumed){
}
}
public void cancel(){interrupt();}
}
1、阻塞库方法(thread.sleep object.wait等)检查线程何时中断,并在发现中断时提前返回
操作:清除中断状态,抛出interruptedException
2、线程在非阻塞状态下中断时,它的中断状态将被设置,如果不触发interruptedException,中断状态将一直保持
while(!Thread.currentThread().isInterrupted()){ //检查中断状态
中断并不会真正的中断一个线程,他仅仅是发出了一个 中断请求,线程收到请求后可以选择处理,也可以选择不处理。系统的有些库函数(阻塞的方法)会关注这个状态,并在接到中断之后抛出异常
注意:中断请求最好不要隐藏。静态的interrupted方法会清除中断状态,因此,如果interrupted方法返回true,可以抛出异常或者是再次调用interrupt方法设置中断状态
中断策略:
决定如何应对中断请求:尽可能迅速退出,如果需要的话进行清理,可能的话通知其他的实体本线程退出。
在任务代码中应该小心的保存中断状态,因为线程不是隶属于该任务的,对于线程池来讲,一个线程上可能会运行多个任务,任务中小心的保存中断状态,线程的所有者才能最终有所作用。对于大多数可阻塞的库函数而言,他们之所以仅仅抛出了InterruptedException,是因为他们知道自己没有权限结束一个本来就不属于他们的线程,所以抛出异常,传给上层代码进一步的决定要采取的策略。在捕获了InterruptedException之后,要恢复中断的状态Thread.currentThread().interrupt();
响应中断在调用可中断的阻塞函数时 的策略1.传递异常,这时你的方法也成为可中断的阻塞方法了public void sleep(int i) throws InterruptedException{Thread.sleep(i);}2.保存中断状态,上层调用者对其处理在catch语句中回复中断状态 --Thread.currentThread().interrupt()3.实现含有阻塞方法的不可取消任务一般来说,含有阻塞方法的任务均可响应中断,可以通过特殊的处理,使任务在退出前保存中断定义一个自有的中断状态,当阻塞的方法响应中断抛出异常时,catch中把自有的中断状态设置为ture,然后在finally块中检查这个自有的中断状态,然后设置Thread 的中断状态。这样只有在任务结束退出的时候才设置的Thread的中断。实现了不可取消的任务。