当Count.run()倒计时锁定获得异常时,Java CountDownLatch会等待超时值

时间:2016-05-18 11:49:20

标签: java multithreading countdownlatch

我正在使用CountDownLatch来处理两个Java线程。我的班级结构如下:

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);

主类等待其他两个线程完成其工作。一旦他们完成工作,它就不会等到超时值(20秒)。我的问题是,如果任何线程被破坏或损坏,则CountDownLatch等待其超时值。有没有办法忽略那个被打断的线程并继续前进而不等待20秒?

2 个答案:

答案 0 :(得分:6)

zapl绝对正确!主线程正在等待超时结束。如果在主线程等待锁存器的过程中进行了线程转储,您将看到如下内容:

"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)

来自await的Javadoc:

  

如果当前计数大于零则为当前线程   因线程调度而被禁用,直到休眠为止   发生以下三件事之一:

     
      
  1. 由于countDown方法的调用,计数达到零;或
  2.   
  3. 其他一些线程会中断当前线程;或
  4.   
  5. 指定的等待时间过去了。
  6.   

在您的情况下,await调用仅因为3)而返回。

CountDownLatch Javadoc中,应该在countDown()块中调用finally方法:

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

答案 1 :(得分:0)

线程被破坏时需要某种通知。一种方法是在线程中手动捕获InterruptedException,然后倒计时错误。

另一种方法是使用Runnable个任务而不是Threads,并使用guavas ListenableFuture来获取错误通知。 This SO Q&amp; A解释得很好。