CountDownLatch await 方法问题:不会在超时时抛出

CountDownLatch await method issue: doesn't throw on timeout

我正在编写一个简单的程序来演示CountDownLatch。这是我的程序:

class Players implements Runnable {
    private int delay;
    private String name;
    private CountDownLatch latch;

    Players(int delay, String name, CountDownLatch latch) {
        this.delay = delay;
        this.name = name;
        this.latch = latch;
    }

    @Override
    public void run() {
        System.out.println("Player" + name + "joined");
        try {
            Thread.sleep(delay);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        latch.countDown();
    }
}
public class LudoDemoUsingCountDownLatch {
    public static void main(String[] args) {
        CountDownLatch latch = new CountDownLatch(4);
        ExecutorService service = Executors.newFixedThreadPool(4);
        service.execute(new Players(11000, "player-1", latch));
        service.execute(new Players(12000, "player-2", latch));
        service.execute(new Players(13000, "player-3", latch));
        service.execute(new Players(14000, "player-4", latch));
        try {
            latch.await(1000, TimeUnit.MILLISECONDS);
            System.out.println("All four playesr joined. game started ");
        } catch (InterruptedException e) {
            System.out.println("cant start the game ");
        }
    }
}

我希望主线程甚至在任何玩家加入之前就应该启动,并且 catch 块中的代码应该执行,因为 await 方法的等待时间小于所有玩家线程的 sleep 方法。但我没有得到那个输出。而是显示所有玩家加入并开始游戏:

输出:

 1. Player-2joined
 2. Player-3joined
 3. Player-1joined
 4. Player-4joined
 5. All four players joined. game started 

您需要检查 CountDownLatch.await 的 return 值。它不会在超时时抛出 InterruptedException;它 returns false.

因此,您的 main 方法的更正版本如下所示:

CountDownLatch latch = new CountDownLatch(4);
ExecutorService service = Executors.newFixedThreadPool(4);
service.execute(new Players(11000, "player-1", latch));
service.execute(new Players(12000, "player-2", latch));
service.execute(new Players(13000, "player-3", latch));
service.execute(new Players(14000, "player-4", latch));
boolean started = false;
try {
    started = latch.await(1000, TimeUnit.MILLISECONDS);
    if (started) {
        System.out.println("All four players joined. game started ");
    }
} catch (InterruptedException e) {
    System.out.println("Interrupted - won't generally be hit");
}
if (!started) {
    System.out.println("Can't start the game");
}

请注意,您可能 打算将 System.out.println("Player" + name + "joined"); 放在 Thread.sleep 调用之后 Player.