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

ThreadPoolExecutor限制线程数

胥玮
2023-03-14

我正在尝试创建一个具有一定数量线程的ThreadPoolExector,但同时,我想控制池队列的大小。所以我使用完整的构造函数创建了执行器:

 BlockingQueue<Runnable> pq =
     new ArrayBlockingQueue<Runnable>(MAX_THREADPOOL_SIZE);
 ThreadPoolExecutor threadPoolExecutor =
     new ThreadPoolExecutor(threadSize, threadSize, THREAD_IDLE_WAIT,
          TimeUnit.SECONDS, pq);

然而,这给了我一个非法辩论例外。如果我将构造函数更改为

new ThreadPoolExecutor(threadSize, **threadSize+1**, THREAD_IDLE_WAIT,
     TimeUnit.SECONDS, pq);

它起作用了。如果我希望理想的线程数和最大线程数相同,为什么它不起作用呢。

共有3个答案

狄鹏
2023-03-14

对恒定数量的线程使用工厂方法。

http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(内景)

然后根据需要设置超时。

ThreadPoolExecutor exec = (ThreadPoolExecutor)Executors.newFixedThreadPool(threadSize);
exec.setKeepAliveTime(THREAD_IDLE_WAIT, TimeUnit.SECONDS);
江飞白
2023-03-14

我看不出你的初始代码为什么会抛出。如果您将来提供完整的例外情况,我们可以提供更具体的帮助。

需要记住的一件事是,一旦队列已满,使用有界阻塞队列将引发异常。这很少是你所期望的。如果查看我对以下问题的回答,您将看到需要配置拒绝执行处理程序(RejectedExecutionHandler):

如果ThreadPoolExecutor命令需要处理的数据太多,如何使其等待?

要从那里进行复制,需要执行以下操作:

final BlockingQueue queue = new ArrayBlockingQueue<Runnable>(200);
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(nThreads, nThreads,
           0L, TimeUnit.MILLISECONDS, queue);
// by default (unfortunately) the ThreadPoolExecutor will throw an exception
// when you submit the 201st job, to have it block you do:
threadPool.setRejectedExecutionHandler(new RejectedExecutionHandler() {
   public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
      // this will block if the queue is full
      executor.getQueue().put(r);
   }
});

最后,如果最大线程大小大于核心线程大小,则必须意识到队列将在分配超过核心大小的任何其他线程之前填满。奇怪但真实。

华俊贤
2023-03-14

来自javadoc:如果corePoolSize或keepAliveTime小于零,或者如果maximumPoolSize小于或等于零,或者如果corePoolSize大于maximumPoolSize。所以他们也可以是平等的。我也尝试过用相同的价值观进行构建,它很有效。也许源代码可以帮助您找出问题所在:

if (corePoolSize < 0 ||
    maximumPoolSize <= 0 ||
    maximumPoolSize < corePoolSize ||
    keepAliveTime < 0)
    throw new IllegalArgumentException();
 类似资料:
  • 以下是Sun创建线程的简单规则: 如果线程数小于corePoolSize,请创建新线程以运行新任务 为什么在队列已满时创建非核心线程?我不明白他们为什么这样做。为什么不在队列为空时创建非核心线程?

  • 问题内容: 我在实践中阅读Java Concurrency,并且有点与线程限制概念混淆。这本书说 当一个对象被限制在一个线程中时,即使该限制对象本身不是一个线程,这种使用也是自动的线程安全的 那么,当一个对象被限制在一个线程中时,没有其他线程可以访问它吗?那就是局限于线程吗?如何将对象限制在线程中? 编辑: 但是,如果我仍然想与另一个线程共享对象怎么办?假设在线程A完成对象O后,线程B想要访问O。

  • 问题内容: 基本上我需要在更多线程中运行〜数百个计算。我只想在paralell中运行一些并行线程,例如5个线程和5个计算。 我正在使用spring框架,@Async选项是自然选择。我不需要全功能的JMS队列,这对我来说有点麻烦。 有任何想法吗 ?谢谢 问题答案: 你检查了吗?你可以定义一个线程池,其中包含最大数量的线程来执行任务。 如果要与结合使用,请在spring-config中使用它:

  • 所以我们有一些游戏服务器在我们的V服务器上运行(我说的这款有8Vcore、4.2GHz和32GB DDR4内存),例如Minecraft。我们的问题是服务器在大约640个线程的情况下耗尽了内存(它不关心栈大小,1024KB、512KB都是相同的结果)。那么有没有办法从我们的系统中得到更多的线程呢? Linux:Debian 9 Virtuozzo容器 Java: openjdk版本“1.8.023

  • 问题内容: 我无法创建新线程。实际上,我编写了一个有点黑的程序,可以接受任何任务(即,它是不受限制的),但是调用了一个附加处理程序- 在我的应用程序中,它会发出警告跟踪表明该池已落后-这为我提供了TPE拒绝创建的非常明确的信息新队列,即使队列中有成千上万的条目。我的构造函数如下: 为什么不创建新线程? 问题答案: 此博客文章介绍了这一难题: 这种线程池的构造根本无法按预期工作。这是由于Thread

  • 我读到有一个线程池,这个池注定要减少创建新线程的成本(至少我这样理解下面的短语): 当您向执行程序发送任务时,它会尝试使用一个池线程来执行此任务,以避免线程的持续生成。[Java7并发Cookbook] 但是,我知道我们没有办法在Java重启线程。 问题:ThreadPoolExecutor如何避免创建新线程?