2015-11-21 20 views
10

Eşzamanlı push/pop öğeleri için kullanıyorum ConcurrentLinkedDeque var, ve ben bir öğe yığınından alıyorsanız bazı async görevleri var ve varsa elemanın komşuları var.ExecutorService üzerinde çalışan tüm görevlerin tamamlanıp tamamlanmadığını nasıl kontrol edilir

örnek kod:

private ConcurrentLinkedDeque<Item> stack = new ConcurrentLinkedDeque<>(); 
private ExecutorService exec = Executors.newFixedThreadPool(5); 

    while ((item = stack.pollFirst()) != null) { 
       if (item == null) { 
       } else { 
        Runnable worker = new Solider(this, item); 
        exec.execute(worker); 
       } 
      } 

    class Solider{ 
     public void run(){ 
      if(item.hasNeighbors){ 
       for(Item item:item.neighbors){ 
        stack.push(item) 
       } 
      } 
     } 
    } 

Ben soru cevaplar ise döngü içinde ek açıklama istiyorum - "Executor herhangi bir görev çalışıyor?"

cevap

24

ExecutorService.execute(Runnable)'u kullanırsanız, tüm Çalışma Alanı'nın yapılıp yapılmadığını kontrol etmenin temiz bir yolu yoktur. Eğer Runnable'da bunu yapmak için bir mekanizma inşa etmedikçe (ki bu benim görüşüme göre özensizdir). Bunun yerine

:
kullanın ExecutorService.submit(Runnable). Bu yöntem, bir çalıştırılabilir sonucun bir tanıtıcısı olan bir Future<?> döndürecektir. Futures'ı kullanmak sonuçları kontrol etmek için temiz bir yol sağlar.

yapmanız gereken tek şey teslim Vadeli listesini tutmak ve sonra Vadeli İşlem ve ya bütün liste yineleme yapabilirsiniz: Bir engelleme yapılacak
    A) tüm gelecekleri için bekleyin veya tüm vadeli işlemlerin bloke olmayan bir şekilde yapıldığını kontrol ediniz. < neyse: Bunun için kullanılan java yöntem zaten var düşündük

List<Future<?>> futures = new ArrayList<Future<?>>(); 
ExecutorService exec = Executors.newFixedThreadPool(5); 

// Instead of using exec.execute() use exec.submit() 
// because it returns a monitorable future 
while((item = stack.pollFirst()) != null){ 
    Runnable worker = new Solider(this, item); 
    Future<?> f = exec.submit(worker); 
    futures.add(f); 
} 

// A) Await all runnables to be done (blocking) 
for(Future<?> future : futures) 
    future.get(); // get will block until the future is done 

// B) Check if all runnables are done (non-blocking) 
boolean allDone = true; 
for(Future<?> future : futures){ 
    allDone &= future.isDone(); // check if future is done 
} 
+0

:

İşte bir kod örnektir! Çözümünüzü kullandım, iyi çalışıyor, teşekkürler! :) – user4129715

+0

Burada geçenlerin amacı ne olurdu? Gelecek olamaz.Yani kendi başına gerçek mi yoksa yanlış mı? Btw - büyük cevap! – User3

+1

@ User3 'allDone'un amacı, vadeli işlemlerin yapılmasının ya da yapılmamasının (' & = 'operatörünü kullanarak) tek bir boole değeri elde etmektir. future.isDone() 'sadece bireysel bir Geleceğin tamamlanıp tamamlanmadığını kontrol etmek için kullanılabilir –