2015-06-28 16 views
5

'daki istisnalar nasıl geri alınır ve işlenir Birden çok iş parçacığı ayarlarında istisnaların üstesinden gelmenin bir yolunu bulmaya çalışıyorum. Bazı görevleri paralel olarak yürütmek istiyorum, her biri (temel olarak, başarısız olan görevi bir yürütme sırasına geri koyarak) tepki vermem gereken bir istisna atabilir. Ancak, iş parçacığı istisnası aslında bir geleceği oluşturmak ve get() yöntemini çağırmak için yalnızca bir yol gibi görünüyor. Ancak, bu aslında çağrıları senkronize çağrılara dönüştürür.Java'nın ExecutorService

ExecutorService executor = Executors.newFixedThreadPool(nThreads); 
Task task = taskQueue.poll(); // let's assume that task implements Runnable 
try { 
    executor.execute(task); 
} 
catch(Exception ex) { 
    // record the failed task, so that it can be re-added to the queue 
} 

Ancak bu durumda tüm görevler başlattı, ancak istisnalar burada bu catch bloğunda yakalanmamak görünmüyor:

Belki bazı kod konuyu açıklığa kavuşturacaktır.

Alternatif yerine dişin bir Future kullanmak ve sonuç almak için olacaktır: istisnalar catch bloğunda tamam yakalanırlarsa Bu durumda

try { 
    Future<?> future = executor.submit(task); 
    future.get(); 
} 
... 

ancak sahip fiyata beklenecek Bu işlem bitene kadar. Böylece, görevler istenildiği gibi sıralı ve paralel olarak yürütülmez.

Neyi eksik? Her birinin görevlerini nasıl yakalayabiliriz İstisnalar ve bunlara nasıl tepki verebilirsiniz?

+0

Ama geleceğin yürütme sen istisna almak tamamlandığında ise (veya başarılı dönüş değeri). İlk yolunuz geleceği değerlendirmedeki istisnaları değil, geleceği geleceğe ekleyerek istisnaları yakalamaya çalışmaktır (ve geleceği atıyorsunuz). –

cevap

2

Bir döngü içinde tüm görevleri tetikleyebilir ve kontrol edebilir/bekliyoruz/diğerinde yeniden denemek:

Map<Future<?>, Task> futures = new HashMap<Future<?>, Task>() 
while(!taskQueue.isEmpty()){ 
    Task task = taskQueue.poll(); 
    Future<?> future = executor.submit(task); 
    futures.put(future, task); 
} 

for(Map.Entry<Future<?>, Task> entry : futures.entrySet()){ 

    try { 
     entry.getKey().get(); 
    } 
    catch(ExecutionException ex) { 
     // record the failed task, so that it can be re-added to the queue 
     // you should add a retry counter because you want to prevent endless loops 
     taskQueue.add(entry.getValue()); 
    } 
    catch(InterrupredException ex){ 
     // thread interrupted, exit 
     Thread.interrupt(); 
     return; 
    } 
} 

HTH Mark

+0

Çok teşekkürler, Mark. Bu çözüm işe yaradı. For döngüsü içindeki girdinin şu şekilde bildirilmesi gerektiğini unutmayın: Map.Entry , Görev> giriş (takas Görev ve Gelecek). –

+0

Geri bildiriminiz için teşekkür ederiz, kodu buna göre değiştirdik. – mp911de

İlgili konular