2016-05-18 7 views
5

İki Java iş parçacığını işlemek için bir CountDownLatch kullanıyorum. aşağıdaki gibi Benim sınıf yapısı şöyledir:Java CountDownLatch, mandalın geri sayımını döndürürken thread.run() öğesinin bir istisna aldığında zaman aşımı değerini bekler

MainClass.java
ThreadOne.java
ThreadTwo.java

MainClass:

CountDownLatch latch = new CountDownLatch(2);   
Thread thread = new Thread(new ThreadOne(latch)); 
thread.start(); 

Thread thread1 = new Thread(new ThreadTwo(latch)); 
thread1.start();   

latch.await(20, TimeUnit.SECONDS); 

Ana sınıfı bekler diğer iki konu işlerini tamamlayana kadar. İşlerini tamamladıkları anda, zaman aşımı değerine (20 saniye) kadar beklemezler. Benim sorunum, herhangi bir iş parçacığı yok veya bozuk olursa CountDownLatch zaman aşımı değeri için bekler. Kesilen ipliği görmezden gelmenin ve 20 saniye beklemeden ilerlemenin bir yolu var mı?

+0

Sizin Threads'larınızın yok edilmesi veya bozulmasıyla ne demek istiyorsunuz? İstisna mı atıyorsun? – Alexander

+4

"latch.countDown()" çağrısını iş parçacığı kodunuzda bir "nihayet" bloğuna taşıyın, böylece ne olursa olsun yürütülür – zapl

cevap

6

zapl kesinlikle haklıdır! Ana iş parçacığı üstesinden gelmek için beklemek. Geçerli sayım büyükse

: await ait Javadoc itibaren

"main" #1 prio=5 os_prio=31 tid=0x00007fa4be002000 nid=0x1303 waiting on condition [0x000000010b74c000] 
    java.lang.Thread.State: TIMED_WAITING (parking) 
    at sun.misc.Unsafe.park(Native Method) 
    - parking to wait for <0x000000076abcb598> (a java.util.concurrent.CountDownLatch$Sync) 
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1037) 
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1328) 
    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:277) 

: Ana iş parçacığı mandalına bekliyor süre içinde bir iş parçacığı dökümü aldı varsa, şöyle bir şey görür sıfır ardından geçerli iş parçacığı iplik zamanlama amaçlarla devre dışı olur ve uykuda yatıyor daha üç şeyden biri olur sonu:

  1. sayımı nedeniyle sıfıra ulaştığında countDown yönteminin çağrılmasına; veya
  2. Diğer bazı dişler geçerli ipliği keser; veya
  3. Belirtilen bekleme süresi geçiyor. Senin durumunda

, await arama) sırf 3 döner. CountDownLatch Javadoc olarak

, countDown() yöntemine çağrı finally blokta yapılmalıydı: Bir iş parçacığı tahrip aldığında

public void run() { 
    try { 
     startSignal.await(); 
     doWork(); // may throw exception 
    } catch (InterruptedException ex) { 
     // handle interruption ... 
    } finally { 
     doneSignal.countDown(); // cause await to return asap 
    } 
} 
0

Bildirimde çeşit gerekir. Bunu yapmanın bir yolu, InterruptedException'u iş parçacığı içinde elle yakalamak ve ardından hatayı geri saymaktır.

Başka bir yol, Threads yerine Runnable görevlerini kullanmak ve hata bildirimleri almak için guavas ListenableFuture'u kullanmaktır. This SO, iyi açıklıyor.

İlgili konular