2017-03-06 39 views
1

我有使用固定线程池的服务,因为这个繁重任务的多于10个实例对我的服务器来说太多了。具有n个线程和n个相应对象的ExecutorService

ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(10); 

我使用它是这样的:

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

现在我需要MyHeavyClassWithCache类的也只有N(10)的实例。而且还需要以某种方式在执行程序中重用它(比现在快得多,然后创建它)。 如何使用ExecutorService管理这类事情。 目标是利用我的MyHeavyClassWithCache类的10个实例之一以达到最多10个线程同时工作(从来没有两个线程与在同一时间同一实例!)

我希望这是足够共同存在的一些Java设计模式来实现这一点。

+1

你在找什么是一个对象池。你可以使用commons-pool来实现ithttp://commons.apache.org/proper/commons-pool/ – seneque

+0

是的,这正是我需要的。我实现了它,迄今为止效果很好。在这里写下您的评论作为答案。非常感谢! –

回答

0

目标是利用我的MyHeavyClassWithCache类的10个实例之一

有几个方法可以做到这对实现这一目标最大10个线程同时工作。最简单的方法可能是使用ThreadLocal<MyHeavyClassWithCache>,以便每个池线程都有自己的“重”类。您的Runnable实例将定义ThreadLocal

另一种方法是从不同的BlockingQueue提交10个HeavyRunnable实例池中,每一个都具有MyHeavyClassWithCache自己的本地实例,有那些出队。这是我之前使用过的一种模式。

的代码可能看起来像:

// 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 S和具有螺纹关机,当他们离队null是单向的。