ThreadPoolExecutor:它如何重用线程

VB_*_*VB_ 7 java concurrency multithreading

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

当您将任务发送到执行程序时,它会尝试使用池化线程来执行此任务,以避免持续产生线程.[Java 7并发手册]

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

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

Bor*_*der 11

它非常简单 - 实质上Thread是睡眠,等待被任务吵醒 - 他们运行该任务然后再次睡觉.

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");
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

BlockingQueue会阻止Thread,而它是空的.当我添加一个项目时,Thread当前被阻止的(s)被唤醒,一个人将接受任务(LinkedBlockingDeque线程安全).当Thread与任务做了它回到睡眠状态.

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

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