微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – ThreadPoolExecutor:它如何重用线程

我读到ThreadPoolExecutor有线程池,这个池注定要降低创建新线程的成本(至少我以这种方式理解下面的短语):

When you send a task to the executor,it tries to use a pooled thread
for the execution of this task,to avoid continious spawning of
threads. [Java 7 Concurrency Cookbook]

但是,据我所知,我们无法在Java中重启线程.

问题:ThreadPoolExecutor如何避免创建新线程?

解决方法

它非常简单 – 本质上线程睡眠,等待被任务唤醒 – 它们运行该任务然后再次睡眠.
public static void main(final String[] args) throws Exception {
    final BlockingQueue<Runnable> blockingQueue = new LinkedBlockingDeque<>();
    final Thread t = new Thread(new Runnable() {

        @Override
        public void run() {
            while (true) {
                try {
                    blockingQueue.take().run();
                } catch (InterruptedException ex) {
                    return;
                }
            }
        }
    });
    t.start();
    blockingQueue.add(new Runnable() {

        @Override
        public void run() {
            System.out.println("Task 1");
        }
    });
    blockingQueue.add(new Runnable() {

        @Override
        public void run() {
            System.out.println("Task 2");
        }
    });
}

BlockingQueue会在空的时候阻塞它.当我添加一个项目时,当前被阻止的线程被唤醒,并且将执行任务(LinkedBlockingDeque是线程安全的).线程完成任务后,它会重新进入休眠状态.

ThreadPoolExecutor的JavaDoc详细描述了逻辑. ThreadPoolExecutor的所有构造函数都采用BlockingQueue< Runnable> – 这应该给你一个提示,因为逻辑是如何工作的.

注意:这与忙碌的等待不一样. BlockingQueue使用wait和notify来挂起和唤醒线程,这意味着池中的线程在没有处理任务时没有做任何工作.基于繁忙等待的方法不起作用,因为线程将阻止所有cpu核心,其轮询不允许程序继续(或至少严重损害它).

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐