gpt4 book ai didi

java - 使用同一对象的线程池

转载 作者:行者123 更新时间:2023-12-03 13:10:32 25 4
gpt4 key购买 nike

我创建了一个线程池,其中每个线程从队列中获取一个对象并对其进行处理。我不确定我是否以正确的方式实现了它。这是代码:

public class HandlerThreadsPool<T> {

private BlockingQueue<T> queue;
private IQueueObjectHandler<T> objectHandler;

private class ThreadClass implements Runnable {

@Override
public void run() {
while (true) {
objectHandler.handleItem(queue.take());
}
}
}

public HandlerThreadsPool(int numberOfThreads, BlockingQueue<T> queue, IQueueObjectHandler<T> dataHandler){

this.queue = queue;
this.objectHandler = dataHandler;
ExecutorService service = Executors.newFixedThreadPool(numberOfThreads);
for (int i = 0; i < numberOfThreads; i++)
service.execute(new ThreadClass());
service.shutdown();
}

}

dataHandler处理对象做一些事情。这样正确吗?
谢谢

最佳答案

首先,在构造函数内部创建,提交并关闭ExecutorService并不是一个好习惯。
shutdown() javadoc

Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.



您没有发布 IQueueObjectHandler,但是对我来说,您的ThreadClass作业将无限运行,如果您不通过在 objectHandler.handleItem(..)内显式抛出一些未经检查的异常来停止它们,那将是当然的,这将是错误的。由于这些无限运行的非守护线程,您可能会遇到JVM终止的问题。 ( JVM graceful termination conditions)
另外,您在执行 InterruptedException时未捕获 queue.take(),这会导致编译时错误。正确处理 InterruptedException可以帮助您停止可能的 shutdownNow()

所以
  • 不要在构造函数中关闭池,这会导致问题。如果您不想在其他地方关机,请使用Runtime.getRuntime().addShutdownHook(..)
  • 使用shutdownNow()实际停止执行程序的线程,如果它们处于无限循环中,请为此在InterruptedException中处理ThreadClass。或者,您可以使用volatile booleanAtomicBoolean标志(指示状态,正在运行/已停止)将其停止。在需要关闭作业时,请在循环中检查标志并将其更改为false
  • ExecutorService service设置为实例变量,而不是局部变量。丢失对运行ExecutorService的引用看起来很糟糕。这可以在其他地方为您提供帮助。
  • 关于java - 使用同一对象的线程池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34771444/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com