1

我是 Java 编程新手,第一次在 Java 中使用 countDown,

我的代码片段是,

CountDownLatch latch=new CountDownLatch(rows*columns); //rows -2 , columns -3
        for (int i = 0; i < rows; i++) {
                    for (int j = 0; j < columns; j++) {
                            GUIView view = getView(1, 1);
                            if(view == null) {
                                if(ViewColumn(j +1) != null){
                                    latch.countDown(); //EDT
                                    continue;
                                }
                                 latch.countDown(); //EDT
                                 break;
                            }   
new Thread(new countDownThread(view,latch)).start(); //Where i do some other processing and do countDown 


                    }
        }
        try {
             logger.log("Before countdown await");
            latch.await();
            logger.log("After countdown await");

        }
        .........
        ........

正如我从另一篇文章中读到的,

CountDownLatch 的缺点/优点之一是,一旦计数达到零,它就不可重复使用,您不能再使用 CountDownLatch。

我的疑问是在 for 循环内使用相同的实例 latch 。如果 CountDownLatch 不可重用,如果第一次迭代 latch.countDown() 开始并且在第三次迭代时变为零会发生什么(第三次迭代的 latch.countDown() 无效??)。

问题是 :

当我调试for循环(使用eclipse)时,当控制到达时latch.await();它就会挂起。但是,如果我只是运行应用程序,则不会发生挂起。

我不太了解 countDown 锁存器的用法。请向我解释一下。

4

2 回答 2

1

当您使用某个值初始化 CountDownLatch 时,例如:

CountDownLatch latch = new CountDownLatch(3);

它基本上意味着当方法:

latch.countDown();

将被触发 3 次,将使用闩锁的类将从 await 方法调用中释放。

当然,您必须确保使用相同的闩锁实例。有关更多信息,请访问不错的教程:http ://tutorials.jenkov.com/java-util-concurrent/countdownlatch.html

于 2015-05-18T11:23:16.003 回答
1

似乎在这里您不使用多线程,并且所有工作都在一个线程中完成,因为您不需要使用CountDownLatch.

latch.await();挂起,因为它等待所有 count任务都将完成(似乎在这里 //rows -2 , columns -3 = 6)并调用latch.countDown();. 在docs中阅读更多信息。

这是一个简单的使用示例,其中t2等待t1

import java.util.concurrent.CountDownLatch;

public class Test {

    public static void main(String... s){
        final CountDownLatch cdl = new CountDownLatch(1);

        Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                int i = 5;
                while(i-- > 0)
                    System.out.println("t2 wait me");
                cdl.countDown();
            }
        });


        Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    cdl.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("done");
            }
        });

        t2.start();
        t1.start();
    }

}
于 2015-05-18T11:25:34.490 回答