现在的位置: 首页 > 综合 > 正文

java线程停止【二】

2013年12月20日 ⁄ 综合 ⁄ 共 1743字 ⁄ 字号 评论关闭

本文内容来自《java并发编程实战》

    如上一篇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]

 

抱歉!评论已关闭.