具有n个线程和n个相应对象的ExecutorService

时间:2017-03-06 12:30:13

标签: java multithreading executorservice

我有使用固定线程池的服务,因为对于我的服务器而言,这个繁重任务的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管理此类事情。 目标是通过使用MyHeavyClassWithCache类的10个实例中的一个来实现最多10个线程同时工作(从来没有两个线程同时具有相同的实例!)

我希望这足以存在一些java设计模式来实现这一点。

1 个答案:

答案 0 :(得分:0)

  

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

有几种方法可以做到这一点。最简单的方法可能是使用ThreadLocal<MyHeavyClassWithCache>,以便每个池线程获得自己的&#34; heavy&#34;类。您的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 null放入队列并且当它们出列null时让线程关闭是一种方法,这是一个挑战。