5

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

MainClass.java
ThreadOne.java
ThreadTwo.java

主类:

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 秒的情况下继续前进?

4

2 回答 2

7

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)

来自的Javadoc await

如果当前计数大于零,则当前线程出于线程调度目的而被禁用并处于休眠状态,直到发生以下三种情况之一:

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

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

CountDownLatchJavadoc 中,对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
    }
}
于 2016-05-18T12:29:52.770 回答
0

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

另一种方法是使用Runnable任务而不是Threads使用番石榴ListenableFuture来获取错误通知。这个SO Q&A 很好地解释了它。

于 2016-05-18T12:30:22.787 回答