2010-07-02 5 views
9

İki iş parçacığı arasında bir başlatma işlemini eşitlemek için CountDownLatch kullanıyorum ve atmak için InterruptedException düzgün işlenmesi hakkında merak ediyordum.CountDownLatch InterruptedException

private CountDownLatch initWaitHandle = new CountDownLatch(1); 
    /** 
    * This method will block until the thread has fully initialized, this should only be called from different threads Ensure that the thread has started before this is called. 
    */ 
    public void ensureInitialized() 
    { 
     assert this.isAlive() : "The thread should be started before calling this method."; 
     assert Thread.currentThread() != this, "This should be called from a different thread (potential deadlock)"; 
     while(true) 
     { 
      try 
      { 
       //we wait until the updater thread initializes the cache 
       //that way we know 
       initWaitHandle.await(); 
       break;//if we get here the latch is zero and we are done 
      } 
      catch (InterruptedException e) 
      { 
       LOG.warn("Thread interrupted", e); 
      } 
     } 
    } 

bu desen mantıklı mı i başlangıçta yazdı

kod bu? Temel olarak InterruptedException'u görmezden gelinceye kadar beklemek iyi bir fikirdir. Sanırım bu durumun kesintiye uğrayacağı durumları anlamıyorum, dolayısıyla onları farklı bir şekilde ele almam gerekip gerekmediğini bilmiyorum.

Neden bir InterruptedException buraya atılır, onu ele almak için en iyi uygulama hangisidir?

cevap

9

Bu, InterruptedException için yapmamanız gereken şeydir. Bir InterruptedException temel olarak, bu iş parçacığının sonlandırılması için bir kibar istektir. İplik temizlenmeli ve mümkün olan en kısa sürede çıkmalıdır. http://www.ibm.com/developerworks/java/library/j-jtp05236.html İşte

ben öyle yapardım:

IBM bu konuda yayınlanan iyi bir makale var

// Run while not interrupted. 
while(!(Thread.interrupted()) 
{ 
    try 
    { 
     // Do whatever here. 
    } 
    catch(InterruptedException e) 
    { 
     // This will cause the current thread's interrupt flag to be set. 
     Thread.currentThread().interrupt(); 
    } 
} 

// Perform cleanup and exit thread. 

bu şekilde yapmaya avantajı böylece şudur: iplik bir engelleme iken kesintiye uğrarsa yönteminde, kesme biti ayarlanmaz ve bunun yerine bir InterruptedException atılır. Bir engelleme yönteminde değilken iş parçacığınız kesintiye uğradıysa, kesintili bit ayarlanacak ve hiçbir özel durum atılmayacaktır. Bu nedenle, bir istisnayla bayrağı ayarlamak için interrupt() numaralı telefonu arayarak, her iki durum da ilk duruma normalleştirilir ve daha sonra döngü koşullu olarak kontrol edilir.

Ek bir bonus olarak, bu, aynı şeyi yapmak için bir boole bayrağını ayarlamak için kendi mekanizmanızı veya arabiriminizi icat etmek yerine, yalnızca kesintiye uğratarak iş parçanızı durdurmanızı sağlar. Eğer Thread kesintiye olabilir meşru bir sebep görmüyorum ve buna makul tepki gelmiyorsa

+0

Biçimlendirmeyi düzeltmeye çalıştım ve bir düzenleme çakışması yaptım. Geri alma seçeneğim yok. Afedersiniz! –

+0

Zaten geri aldım. Yardımın için teşekkürler! Yanlış olduğunu fark ettim, ancak daha sonra metnin duvarını yazarken aynı zamanda düzeltmeye karar verdim. – jdmichal

+0

Aslında hayır, sadece geri dönüştürmek istediğiniz düzenlemede değil, ** - ** geri yüklemek istediğiniz düzenlemede geri almayı tıklattığınız Vikipedi için kullanıyorum. –

2

, ben uygulama mısın

catch (InterruptedException e){ 
     throw new AssertionError("Unexpected Interruption",e); 
} 

O yol yapmalıyım derdim Böyle bir kesinti meydana geldiğinde açıkça başarısız olur ve test sırasında keşfetmeyi kolaylaştırır. Ardından uygulamanın nasıl işleyeceğini veya tasarımda herhangi bir sorun olup olmadığını düşünebilirsiniz.