Java Executors 和每线程(不是每工作单元)对象?

标签 java thread-safety threadpool executor

我有一项任务可以从线程池设计模式中获益(许多小任务可以并行执行)。我最初从头开始实现了一个简单的线程池,n 个 Runnable 都从同一个 ConcurrentLinkedQueue 中拉取工作单元,直到队列为空,然后终止。然后我决定“嘿,让我们试试 Java 中的 Executor,因为它可能比我天真设计的系统经过更好的测试并且更可靠。”问题:在我的实现中,每个线程一直持续到队列为空,使用 while (!queue.isEmpty()),并获得自己的非线程安全对象实例,我们称它为 SlowObject foo,构造起来比较费时。尝试将所有进入 Executor 池的 Runnable 传递给时间效率低下的对象实例失败,因为它不是线程安全的。为每个 Runnable 创建一个新的 SlowObject 实例是不可取的,因为它们的构造成本很高。

有没有办法说“我们使用了多少个线程?让我们为每个线程创建一个 SlowObject,然后让 Runnables 检测我们在哪个线程上并查找正确的对象使用?”这听起来很脆弱且容易失败——不过我不确定我应该关注哪种设计模式。

最佳答案

您最好使用资源池。使用这样的东西:

public class SlowObjectPool {
    private static final int POOL_SIZE = 10;
    private BlockingQueue<SlowObject> slowObjectQueue = new ArrayBlockingQueue(POOL_SIZE);

    public SlowObjectPool() {
        for (int i = 0; i < POOL_SIZE; i++) {
            slowObjectQueue.put(new SlowObject());
        }
    }

    public SlowObject take() throws InterruptedException {
        return slowObjectQueue.take();
    }

    public void release(SlowObject slowObject) {
        // TODO You may want to log a warning if this is false
        slowObjectQueue.offer(slowObject);
    }
}

您可能还想将其设为单例。然后在你的runnables中:

public class MyRunnable implements Runnable {

    private SlowObjectPool pool;

    public MyRunnable(SlowObjectPool pool) {
        this.pool = pool;
    }

    @Override
    public void run() {
        // The next line blocks until a SlowObject is available
        SomeObject someObject = null;
        try {
            someObject = pool.take()
            // Do something with someObject
        } catch (InterruptedException ex) {
            // Thread is being ended, allow to end
        } finally {
            if (someObject != null)
                pool.release(someObject);
        }
    }
}

这将在第一次创建池时立即创建所有对象,而不是动态创建它们,这样您的可运行对象就不必等待创建 SomeObject 实例。

关于Java Executors 和每线程(不是每工作单元)对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12465473/

相关文章:

java - FilterLock 锁定函数中的 java while 循环测试用例中的奇怪字符(向后 "E")

java - 在 CompletableFuture 回调中为类成员属性设置值是否线程安全?

java - 执行人服务。当所有线程都终止时如何等待

java - 线程返回线程池后ThreadLocal对象会被清空吗?

mysql - Web 应用程序卡住。我如何找到原因?

java - 选择实体中包含的列表的子集

jdbc - 在sqlite上调用createArrayOf方法时出现java.lang.AbstractMethodError : org. sqlite.Conn.createArrayOf错误

java - 与 Google OpenID 服务器通信返回 400

java - Java 中的继承和对象类型

php - 既然 Homebrew 不再支持 --with-thread-safety,如何下载线程安全的 PHP?