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

标签 java multithreading queue threadpool threadpoolexecutor

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

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/

    相关文章:

    python - 如何等到信号

    android - 如何将图像下载器移动到 Android 上的单独线程中?

    python - 了解 os.fork 和 Queue.Queue

    java - 我的队列(链接列表)中的空指针

    c++ - 在 C++ 中查找队列的重复状态(顺序相同的元素)

    java - 奇怪的黑莓问题 - 新版本突然请求访问权限

    java - Android studio 使用相同的 key 构建所有包

    java - 当 java 进程终止时捕获

    java - LIBGDX - 加载 libgdx/测试很困难

    c - Solac 单线程 C 应用程序