本文内容来自《java并发编程实战》
如上一篇java线程停止【一】,利用cancelled标志在一定场景可以停止线程任务,然而在某些场景,利用cancelled标志可能让任务陷入死循环。例如:生产者-消费者模式中,如果生产者生成速度超过消费者速度,那么生产者将阻塞,而此时消费者打算取消生成任务,消费者调用了生产者的cancel方法,消费者退出了,那么生产者永远也不会退出(因为生产者阻塞,无法检查cancelled标记)。
java API通过一种线程中断机制,通过这种协助机制来告诉线程在适当的适合停止当前工作。每个线程都有一个boolean类型的中断状态。当中断线程时(调用interrupt方法),线程的中断状态设置为true,阻塞方法库,例如Thread.sleep,Object.wait等都会检查线程合适中断,并在中断时提前返回。JVM不保证线程立即停止,但会在适时检查到中断标记,并停止线程任务。
示例:
如上一篇java线程停止【一】,利用cancelled标志在一定场景可以停止线程任务,然而在某些场景,利用cancelled标志可能让任务陷入死循环。例如:生产者-消费者模式中,如果生产者生成速度超过消费者速度,那么生产者将阻塞,而此时消费者打算取消生成任务,消费者调用了生产者的cancel方法,消费者退出了,那么生产者永远也不会退出(因为生产者阻塞,无法检查cancelled标记)。
java API通过一种线程中断机制,通过这种协助机制来告诉线程在适当的适合停止当前工作。每个线程都有一个boolean类型的中断状态。当中断线程时(调用interrupt方法),线程的中断状态设置为true,阻塞方法库,例如Thread.sleep,Object.wait等都会检查线程合适中断,并在中断时提前返回。JVM不保证线程立即停止,但会在适时检查到中断标记,并停止线程任务。
示例:
public class ThreadCancell2 {
static class PrimeGenerator extends Thread
{
private final BlockingQueue<BigInteger> primes = new LinkedBlockingQueue<BigInteger>();
public void run()
{
try
{
BigInteger p = BigInteger.ONE;
while(!Thread.currentThread().isInterrupted())
{
p = new BigInteger(String.valueOf(getNextPrime(p.intValue()))); //首先计算下一个素数
primes.put(p); //然后存入到queue中
}
}
catch(InterruptedException e)
{
System.out.println("Thread:"+Thread.currentThread().hashCode()+" is interrupted by main thread.");
}
}
public BlockingQueue<BigInteger> getPrimes()
{
return this.primes;
}
public void cancel(){interrupt();}
public int getNextPrime(int n)
{
int nextPrime = n;
for(int j=n; ; j++)
{
boolean isPrime = false;
int stopNum = (int)(Math.sqrt(j)+1);
//System.out.println(j+","+stopNum);
for(int i=2; i<=stopNum; i++)
{
//System.out.println(j+"/"+i+"="+j/i);
if(j%i == 0)
break;
if(i == stopNum)
isPrime = true;
}
if(isPrime)
{
nextPrime = j;
break;
}
}
return nextPrime;
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
PrimeGenerator generator = new PrimeGenerator();
generator.start();
try
{
Thread.sleep(10);
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
generator.cancel();
}
System.out.println(generator.hashCode());
System.out.println(generator.getPrimes());
}
}
执行结果(每次不一样):
28737396
Thread:28737396 is interrupted by main thread.
[3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109]