当前位置: 首页 > 知识库问答 >
问题:

ThreadPoolExecutor:它如何重用线程

刘高驰
2023-03-14

我读到ThreadPoolExecutor有一个线程池,这个池注定要减少创建新线程的成本(至少我这样理解下面的短语):

当您向执行程序发送任务时,它会尝试使用一个池线程来执行此任务,以避免线程的持续生成。[Java7并发Cookbook]

但是,我知道我们没有办法在Java重启线程。

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

共有1个答案

史智志
2023-03-14

这很简单-本质上是线程的睡眠,等待被任务唤醒-他们运行该任务,然后再次睡眠。

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将在线程为空时阻止该线程。当我添加一个项目时,当前被阻止的Thread(s)将被唤醒,其中一个将执行该任务(LinkedBlockingDeque是线程安全的)。当线程完成任务后,它将返回睡眠状态。

ThreadPoolExecator的JavaDoc详细描述了逻辑。ThreadPoolExecator的所有构造函数都需要一个BlockingQueue

注意:这和忙着等待不同。BlockingQueue使用waitnotify来挂起和唤醒线程s,这意味着池中的线程s在不处理任务时没有做任何工作。基于忙等待的方法不起作用,因为线程s将阻塞所有CPU内核,其轮询不允许程序继续(或至少严重损害程序)。

 类似资料:
  • 问题内容: 我正在尝试同时使用和。 由于每个池(毕竟是一个池)都将线程重用,这意味着无法正常工作,因此出现了故障。现在这个问题对我来说似乎很明显,但要追踪它尤为困难。 我这样使用,以便几个顶级进程中的每个进程都有自己的数据库连接以及它产生的任何子进程。我不只是使用一个共享的连接池,因为在提交数据库和/或准备大量重复使用的PreparedStatement之前,每个顶级进程都会对其连接进行很多多步骤

  • 以下是Sun创建线程的简单规则: 如果线程数小于corePoolSize,请创建新线程以运行新任务 为什么在队列已满时创建非核心线程?我不明白他们为什么这样做。为什么不在队列为空时创建非核心线程?

  • 我正在尝试创建一个具有一定数量线程的ThreadPoolExector,但同时,我想控制池队列的大小。所以我使用完整的构造函数创建了执行器: 然而,这给了我一个非法辩论例外。如果我将构造函数更改为 它起作用了。如果我希望理想的线程数和最大线程数相同,为什么它不起作用呢。

  • 本文向大家介绍ThreadPoolExecutor线程池的使用方法,包括了ThreadPoolExecutor线程池的使用方法的使用技巧和注意事项,需要的朋友参考一下 ThreadPoolExecutor ThreadPoolExecutor线程池,java提供开发框架,管理线程的创建、销毁、优化、监控等。 有4种不同的任务队列: 1.ArrayBlockingQueue:基于数组结构的任务队列。

  • 如果正在运行的线程少于corePoolSize线程,则执行器宁愿添加一个新线程,而不是排队。2)如果corePoolSize或更多线程正在运行,则执行器更喜欢将请求排队,而不是添加新线程。 如果请求无法排队,将创建一个新线程,除非该线程将超过maximumPoolSize,在这种情况下,任务将被拒绝。 第一种情况是可以的,但我想要的是,当核心线程被利用时,任务不需要排队(即使在有界队列的情况下,比

  • javadoc表示,重用线程。这怎么可能?一个线程只能通过调用启动一次。那么他们是如何实施的呢?此服务的线程在无限循环中运行,它们的-s会按需更换吗?