【问题标题】:ExecutorService with n threads and n corresponding objects具有 n 个线程和 n 个对应对象的 ExecutorService
【发布时间】:2017-03-06 12:30:12
【问题描述】:

我有使用固定线程池的服务,因为超过 10 个这个繁重任务的实例对我的服务器来说太多了。

ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10);

我使用它是这样的:

Runnable command = new Runnable() {
        @Override
        public void run() {
            MyHeavyClassWithCache myHeavyClassWithCache=new MyHeavyClassWithCache();
        }
    };
    Future<ScreenImage> feature = executor.submit(command,myHeavyClassWithCacheResult);

现在我只需要 n (10) 个 MyHeavyClassWithCache 类的实例。并且还需要在执行器中以某种方式重用它(比我现在创建它要快得多)。 我如何使用 ExecutorService 来管理这种事情。 目标是通过使用我的 10 个 MyHeavyClassWithCache 类实例之一来实现最多 10 个线程同时工作(永远不会有两个线程同时具有相同的实例!)

我希望这足够普遍,存在一些 java 设计模式来实现这一点。

【问题讨论】:

  • 您正在寻找的是一个对象池。可以使用commons-pool来实现http://commons.apache.org/proper/commons-pool/
  • 是的,这就是我需要的。我实现了它,到目前为止效果很好。在此处写下您的评论作为答案。非常感谢!

标签: java multithreading executorservice


【解决方案1】:

目标是通过使用我的 10 个 MyHeavyClassWithCache 类实例之一来实现最多 10 个线程同时工作

有几种方法可以做到这一点。最简单的方法可能是使用ThreadLocal&lt;MyHeavyClassWithCache&gt;,以便每个池线程都有自己的“重”类。您的 Runnable 实例将定义 ThreadLocal

另一种方法是将 10 个 HeavyRunnable 实例提交到您的池中,每个实例都有自己的本地 MyHeavyClassWithCache 实例,并让这些实例从不同的 BlockingQueue 出列。这是我以前使用过的模式。

代码可能类似于:

// runnable that dequeues from a blocking queue and keeps a heavy instance
private static class HeavyRunnable implements Runnable {
    private final MyHeavyClassWithCache heavy = new MyHeavyClassWithCache();
    private final BlockingQueue<Runnable> runnableQueue;
    public HeavyRunnable(BlockingQueue<Runnable> runnableQueue) {
        this.runnableQueue = runnableQueue;
    }
    public void run() {
        while (!Thread.currentThread.isInterrupted()) {
             Runnable runnable = runnableQueue.take();
             // if we see a null then stop running
             if (runnable == null) {
                 break;
             }
             runnable.run();
        }
    }
}

...
final ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10);
final BlockingQueue<Runnable> runnableQueue = new LinkedBlockingQueue<>();
newFixedThreadPool.add(new HeavyRunnable(runnableQueue));
...
runnableQueue.add(new Runnable() { ... });
...

关闭这些后台繁重的可运行程序有点挑战,但将 10 个 nulls 放入队列并在线程出队时关闭 null 是一种方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-06
    • 2012-01-09
    • 2021-06-03
    • 2013-08-16
    • 2012-08-23
    • 2021-11-25
    • 2018-09-23
    • 1970-01-01
    相关资源
    最近更新 更多