2016-02-12 15 views
5

Avantaj önce ve her görev yürütülmesinden sonra denirThreadPoolExecutor'ı geçersiz kılarExecute yöntemi - herhangi bir cons? Kanca yöntemleri

beforeExecute(Thread, Runnable) ve afterExecute(Runnable, Throwable)

beforeExecute(Thread, Runnable) ve afterExecute(Runnable, Throwable) yöntem. Bunlar yürütme ortamını değiştirmek için kullanılabilir; Örneğin, ThreadLocals reinitializing istatistikleri toplamak veya günlük girişlerini

Ben yakalanmamış istisnalar işlemek için Özel'i ThreadPoolExecutor kullanıyorum ekledi. Runnable ve Callable numaralı telefonlara try{} catch{} blokları ekleyebilirim ancak geliştiriciyi bu blokları Runnable ve Callable görevlerine eklemek için zorlayamayacağınız bir senaryo varsayın.

Bu CustomThreadPoolExecutor, aritmetik durum simüle etmek için Sıfır afterExecute() aşağıdaki gibi ThreadPoolExecutor yöntemi (ı atanmış değişken b değeri geçersiz kılar.

import java.util.concurrent.*; 
import java.util.*; 

class CustomThreadPoolExecutor extends ThreadPoolExecutor { 

    public CustomThreadPoolExecutor() { 
     super(1,10,60,TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(1000)); 
    } 

    protected void afterExecute(Runnable r, Throwable t) { 
    super.afterExecute(r, t); 
    if (t == null && r instanceof Future<?>) { 
     try { 
     Object result = ((Future<?>) r).get(); 
     System.out.println(result); 
     } catch (CancellationException ce) { 
      t = ce; 
     } catch (ExecutionException ee) { 
      t = ee.getCause(); 
     } catch (InterruptedException ie) { 
      Thread.currentThread().interrupt(); // ignore/reset 
     } 
    } 
    if (t != null) 
     t.printStackTrace(); 
    } 
} 


public class CustomThreadPoolExecutorDemo{ 

    public static void main(String args[]){ 
     System.out.println("creating service"); 
     //ExecutorService service = Executors.newFixedThreadPool(10); 
     CustomThreadPoolExecutor service = new CustomThreadPoolExecutor(); 
     service.submit(new Runnable(){ 
       public void run(){ 
        int a=4, b = 0; 
        System.out.println("a and b="+a+":"+b); 
        System.out.println("a/b:"+(a/b)); 
        System.out.println("Thread Name in Runnable after divide by zero:"+Thread.currentThread().getName()); 
       } 
      }); 
     service.shutdown(); 
    } 
} 

submit() yana çerçeveye özel gizler, I afterExecute() yöntem geçersiz adres yakalamak İstisna. Bu yöntemde

, aşağıda deyimi ile çağrı engelleme ekledi

Object result = ((Future<?>) r).get(); 

Şu anda 10 tane queue capacity as 1000 tane var. Varsayıyorum benim Runnable tamamlamak için 5 saniye sürüyor. Ben herhangi bir performans yükü VEYA bu yaklaşımla herhangi bir olumsuz yönleri üstlenmeden ediyorum, afterExecute() yöntemini geçersiz kılarak

?

+2

de görebileceğiniz gibi icra ve performansı hakkında Tahmin iyi bir şey, sadece kriter ile ve kodları olmadan kodu değil ve ilgili değişiklikler olup olmadığını kontrol status >= NORMAL sahiptir. http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – Jack

cevap

1

Hayır, engelleme çağrısı yükü getirmek olmaz onun Eğer void runWorker(Worker w)

beforeExecute(wt, task); 
Throwable thrown = null; 
try { 
    task.run(); 
} catch (RuntimeException x) { 
    thrown = x; throw x; 
} catch (Error x) { 
    thrown = x; throw x; 
} catch (Throwable x) { 
    thrown = x; throw new Error(x); 
} finally { 
    afterExecute(task, thrown); 
} 
+0

Ancak bazı durumlarda, benim() hizmeti iletişim sorunları (service.submit() ve call.de()) çağrısı()) –

+0

Evet, 'get()' bloke edebilir, ancak method afterExecute Runnable r, Throwable t) 'korunur ve (FutureTask semanticsini değiştirmediyseniz) görev bittikten sonra' ThreadPoolExecutor' _only_ olarak adlandırılır. – dezhik

1

Daha iyi bir çözüm, Geleceğe bekle submit() döndü ve sonra da ana iş parçacığı istisna işleyebilir yerine vasisi hack sizin için yazdırmak için.

diğer alternatif arzu durum işleme uygulayan Runnable ortak tabanı, örneğin kullanmak olacaktır: iştir çünkü tamamlanmış,

public abstract class BaseRunnable implements Runnable { 
    public final run() { 
    try { 
     runImpl(); 
    } catch(Throwable t) { 
     t.printStackTrace(); 
    } 
    } 
    protected abstract runImpl() throws Exception; 
} 
+0

Bu, istisnaları yakalayan FutureTask ile çalışmayacak ve setException (ex); 've ayrıca CancellationException ile çalışmaz. İstisna her zaman yakalanır. – dezhik

+0

ancak bu durumda, future.get() ana iş parçacığını engeller. –

+0

@dezthink: Hatta ana kodda aşağıdaki kodu eklediyseniz bile Callable çalışacaktır (daha önce yapmıştım (AfterExecute yaklaşımından önce overidding'den önce): gelecek.get() denemek {} yakalamak {} blok –

İlgili konular