Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-COUNTDOWNLATCH中的计数_Java_Countdownlatch - Fatal编程技术网

Java-COUNTDOWNLATCH中的计数

Java-COUNTDOWNLATCH中的计数,java,countdownlatch,Java,Countdownlatch,在运行每个线程时,为什么countdown.getCount()总是打印“3”,即使在上一个线程已经调用了countdown.countdown()并将闩锁计数减少了1之后 我有点想知道Java是如何知道锁存计数已经达到0的,这样它就可以释放所有3个线程 import java.util.concurrent.CountDownLatch; class b { static final CountDownLatch countdown = new CountDownLatch(3); pub

在运行每个线程时,为什么countdown.getCount()总是打印“3”,即使在上一个线程已经调用了countdown.countdown()并将闩锁计数减少了1之后

我有点想知道Java是如何知道锁存计数已经达到0的,这样它就可以释放所有3个线程

import java.util.concurrent.CountDownLatch;

class b {
static final CountDownLatch countdown = new CountDownLatch(3);

public static void main(String[] args) {

    for (int i = 0; i < 3; ++i) {
        Thread t = new Thread() {
            public void run() {
                System.out.printf("Starting on %d other threads.\n",
                        countdown.getCount());
                countdown.countDown();
                System.out.printf("new on %d other threads.\n",
                        countdown.getCount());
                try {
                    countdown.await(); // waits until everyone reaches this
                                        // point
                    // System.out.println("Go again : "
                    // +countdown.getCount());
                } catch (Exception e) {
                }
            }
        };
        t.start();

    }
    System.out.println("Go");
}
import java.util.concurrent.CountDownLatch;
b类{
静态最终倒计时闩锁倒计时=新倒计时闩锁(3);
公共静态void main(字符串[]args){
对于(int i=0;i<3;++i){
线程t=新线程(){
公开募捐{
System.out.printf(“从%d个其他线程开始。\n”,
getCount());
倒计时;
System.out.printf(“在%d个其他线程上新建。\n”,
getCount());
试一试{
倒计时。wait();//等待,直到每个人都达到这个目标
//点
//System.out.println(“再次转到:”
//+倒计时。getCount());
}捕获(例外e){
}
}
};
t、 start();
}
System.out.println(“Go”);
}

}您正在并行启动3个线程。根据启动速度的不同,它们可以在任何线程调用
倒计时()
(至少对于“开始…”行)之前打印“3”。然而,“new on…”行应该打印出一些介于2和0之间的数字范围。

当线程并行运行时,所有三个线程都打印“从3开始…”,并且计数在线程执行倒计时()之前不会更改。为了真正理解发生了什么,我建议您在打印语句之前预先添加System.nanoTime()和线程名称,如下所示:

...
Thread t = new Thread("Thread-" + i) { 
...
System.out.printf("%d> %s: Starting on %d other threads.\n", System.nanoTime(), getName(), countdown.getCount());
countdown.countDown();
System.out.printf("%d> %s: new on %d other threads.\n", System.nanoTime(), getName(), countdown.getCount());
有时您会得到如下输出,这可能会给您一种印象,即线程2忽略了线程1对倒计时的调用:

1407489646569321000> Thread-0: Starting on 3 other threads.
1407489646569324000> Thread-1: Starting on 3 other threads.
1407489646602463000> Thread-1: new on 1 other threads.
1407489646569513000> Thread-2: Starting on 3 other threads.
1407489646602107000> Thread-0: new on 2 other threads.
1407489646603275000> Thread-2: new on 0 other threads.
然而,情况并非如此,我们可以通过查看时间戳来验证操作的正确顺序。输出中的混乱是由于线程调度中固有的不可预测性造成的,这取决于哪个线程获得cpu拼接

话虽如此,它们可能并不总是打印3,这取决于线程调度或延迟。例如,尝试放置一个Thread.sleep(..),如下所示:

public static void main(String[] args) throws Exception {
    for (int i = 0; i < 3; ++i) {
        Thread t = new Thread() {
            public void run() {
                 /* As before */
            }
        };
        t.start();
        Thread.sleep(100); // Artificial Delay
    }
}
在内部,CountDownLatch维护先进先出的等待队列(请参阅.AbstractQueuedSynchronizer)。计数的值是同步的,只有当计数变为0或其他线程中断等待的线程时,等待的线程才会被释放。这是闩锁用来跟踪所有线程何时到达闩锁的机制

如果您对在测试环境中理解闩锁感兴趣,请签出
希望这有助于澄清您对程序行为的调查。

逻辑错误出现在“在上一个线程已经调用countdown.countdown()之后”:它可能没有-在那里工作正常。如果你幸运的话,它的行为和你预期的一样。这就是未定义的多线程行为的美妙之处。如果这一切都是一起开始的,那么Java如何知道(更新锁存计数)线程可以从等待中释放出来?@user547453-我被你的问题弄糊涂了。当闩锁达到0时,
wait()
调用返回。这将在所有线程调用
countDown()
后立即执行。
1407490223575404000> Thread-0: Starting on 3 other threads.
1407490223607879000> Thread-0: new on 2 other threads.
1407490223676233000> Thread-1: Starting on 2 other threads.
1407490223676818000> Thread-1: new on 1 other threads.
1407490223777623000> Thread-2: Starting on 1 other threads.
1407490223778221000> Thread-2: new on 0 other threads.