2015-11-17 24 views
5

Önbelleğe alınmış bir iş parçacığı havuzu oluşturmak istiyorum, ancak sabit olanı olarak işlev görür. Şu anda bu kodu vardır: Ben kodu çalıştırırsanızİş parçacığı havuzu yeniden boyutlandırılıyor

public class BackgroundProcesses { 

    public static void main(String[] args) throws InterruptedException, ExecutionException { 
     //ExecutorService threadPool2 = Executors.newCachedThreadPool(); 
     ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>()); 
     for (int i = 0; i < 800; i++) { 
      Callable<String> task = new Task(); 
      threadPool.submit(task); 
     } 
    } 
} 

class Task implements Callable<String> { 

    @Override 
    public String call() throws Exception { 
     Thread.sleep(100); 
     System.out.println(Thread.currentThread().getName() + " is ready"); 
     return ""; 
    } 
} 

alıyorum çıktı:

pool-1-thread-1 is ready 
pool-1-thread-2 is ready 
pool-1-thread-1 is ready 
pool-1-thread-2 is ready 
... 

sadece 2 konu tüm çalışmaları yapıyoruz ve hiçbir yeni çalışan iş parçacığı havuzuna eklenir Anlamı. Görevler kuyrukta beklerse threadpool daha fazla iş parçacığı üretmemeli (benim durumumda 10'a kadar)?

Executors.newCachedThreadPool() kullanmak istemiyorum, çünkü maksimum iş parçacıklarında üst sınır yok ve corePoolSize 0 var. Daha iyi yanıt vermek için bazı iş parçacıklarının her zaman hazır olmasını istiyorum. 1 -----

----- edit cevap için size Aleksey ederiz. Kuyruktaki kapasitenin ayarlanması beklendiği gibi davranıyor, ama şimdi yeni bir problemim var.

Arka plandaki görevlerin miktarı çok değişkendir. Çoğu zaman 0 ancak kısa süreler boyunca 50 eşzamanlı görevlere kadar gidebilir. Bunu halletmenin etkili bir yolu ne olurdu? Çoğu arka plan görevinin kısa ömürlü olacağını (< 1s), ancak birkaç uzun ömürlü görevlerin (> 1 dk) olacağını unutmayın. Bu gibi benim ThreadPool'da kurarsanız

:

ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(10)); 

Ben büyük olasılıkla yoğun kullanım ile RejectedExecutionException alacak. Böyle yukarı threadpool set Ancak eğer:

ExecutorService threadPool = new ThreadPoolExecutor(2, 10, 180, TimeUnit.SECONDS, new LinkedBlockingQueue<>(200)); 

Ardından yeni çalışan iş parçacığı hiç eklenecektir çünkü kuyruk olmaz dışarı max.

CPU'nun en az 4 çekirdeği vardır, bu yüzden bence bu savurganlık olur. Ve çoğu zaman herhangi bir arka plan görevi yoktur (zamanın% 80'i), bu yüzden sabit bir iş parçacığı havuzu tutmak benim düşünceme göre de israf olacaktır.

cevap

4

ThreadPoolExecutor Javadoc diyor ki:

yeni bir görev (Runnable) yürütmek yöntemde gönderilirse

ve corePoolSize parçacığı daha az çalışan, yeni bir iş parçacığı hatta diğer ise, isteği yerine için oluşturulan çalışan iş parçacığı boşta. koşu, yeni bir iş parçacığı oluşturulur maximumPoolSize parçacığı daha corePoolSize fazla ama daha az var ise kuyruğu dolu yalnızca

o sayısına bir üst sınır yoktur, çünkü LinkedBlockingQueue, asla dolu elemanların new LinkedBlockingQueue()'un new LinkedBlockingQueue(10)'a değiştirilmesi bunu çözecektir.

+0

Bunu temizlediğiniz için teşekkür ederiz. Ama şimdi sıralı ve tüm aktif parçacıklar kadar doldurulur beri RejectedExecutionException alıyorum (havuz boyutu = 10, aktif thread = 10, sıralı görevleri = 10). –

İlgili konular