运行中止一个线程

并发概念汇总html

http://www.letiantian.me/2015-05-27-java-concurrency-summary/java

并发的系统文章多线程

http://www.cnblogs.com/dolphin0520/category/602384.html并发

http://www.cnblogs.com/timlearn/tag/Java%E5%B9%B6%E5%8F%91/this

http://blog.csdn.net/ghsau/article/category/1707779spa

最简单的java线程池与任务队列.net

http://www.cnblogs.com/null7/archive/2012/09/20/2696108.html线程

中断机制htm

http://www.cnblogs.com/timlearn/p/4008783.htmlblog

一.运行一个线程

  运行一个线程的方法十分简单,咱们只需调用Thread实例的start()方法便可,当咱们调用start()方法以后,Java虚拟机会为咱们建立一个线程,而后在该线程中运行run()方法中定义的任务,真正实现多线程。

    在这里,必须强调的是应该调用start()方法,而不是run()方法,直接调用run()方法,虚拟机不会新建线程运行任务,只会在当前线程执行任务,没法实现多线程并发,因此应该调用start()方法。

二.中止一个线程

(1)标志位方法

  在任务中定义一个标志位,而后任务会按期查看标志位,若是设置了标志位,则任务结束。注意,标志位必要设置为volatile类型。

咱们使用这项技术来枚举素数。

public class PrimeGenerator implements Runnable {
    private final List<BigInteger> primes = new ArrayList<BigInteger>();
    private volatile boolean cancelled;
 
    public void run() {
        BigInteger p = BigInteger.ONE;
        while (!cancelled) {
            p = p.nextProbablePrime();
            synchronized (this) {
                primes.add(p);
            }
        }
    }
 
    public void cancel() {
        cancelled = true;
    }
 
    public synchronized List<BigInteger> get() {
        return new ArrayList<BigInteger>(primes);
    }
}

 当cancel()方法调用后,while就会结束,整个线程也会结束。

(2)使用中断中止线程

  在(1)中的使用标志位的方法中,有一个问题,若是线程的任务是阻塞任务,那么线程在阻塞时将没法去查看标志位,所以也没法中止。

  当出现这种状况时,咱们可使用中断,有部分阻塞库方法是支持中断的,线程中断是一个协做机制,线程能够经过这种机制来通知另外一个线程,告诉它在合适或者可能的状况下中止当前的工做,

并转而执行其它的工做。

  修改上面的ArrayList为BlockingQueue,BlockingQueue的put()是能够阻塞的,若是还使用标志位的方法,那么当put阻塞后,将没法再执行while判断,这时咱们就可使用中断标志位的方法来判断结束线程。,

public class PrimeProducer extends Thread {
    private final BlockingQueue<BigInteger> queue;
 
    PrimeProducer(BlockingQueue<BigInteger> queue) {
        this.queue = queue;
    }
 
    public void run() {
        try {
            BigInteger p = BigInteger.ONE;
            while (!Thread.currentThread().isInterrupted())
                queue.put(p = p.nextProbablePrime());
        } catch (InterruptedException consumed) {
            /* Allow thread to exit */
        }
    }
 
    public void cancel() {
        interrupt();//Thread.interrupt()
    }
}

   这时,咱们注意到,cancel()调用时,设置了当前线程的中断标志位为true,BlockingQueue的put()方法能够响应中断,并从阻塞状态返回,返回后,while语句检测到中断位被标志,而后结束整个while

循环,从而结束线程。

(3)不能响应中断的阻塞方法

  若是阻塞方法能够响应中断,咱们就可使用(2)中的方法结束线程,可是还有一些阻塞方法不能响应中断。这里就要经过关闭底层资源,让代码throw异常的方式来结束线程。(略)

相关文章
相关标签/搜索