2017-03-06 42 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是單向的。