Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/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 了解启动线程和可能涉及的数据竞争_Java_Multithreading - Fatal编程技术网

Java 了解启动线程和可能涉及的数据竞争

Java 了解启动线程和可能涉及的数据竞争,java,multithreading,Java,Multithreading,我正在阅读B.Goetz Java并发性的实践,现在我在读关于同步器的部分。他将锁存器描述为一种同步器,并提供了倒计时锁存器的典型用例: public class TestHarness{ public long timeTask(int nThreads, final Runnable task){ final CountDownLatch startGate = new CountDownLatch(1); final CountDownLatch

我正在阅读B.Goetz Java并发性的实践,现在我在读关于同步器的部分。他将
锁存器
描述为一种同步器,并提供了
倒计时锁存器
的典型用例:

public class TestHarness{

    public long timeTask(int nThreads, final Runnable task){

        final CountDownLatch startGate = new CountDownLatch(1);
        final CountDownLatch endGate = new CountDownLatch(nThreads);

        for(i = 0; i < nThreads; i++) {
           Thread t = new Thread(){
              try{
                  startGate.await();
                  try{
                      task.run();
                  } finally {
                      endGate.countDown();
                  }
              } catch (InterruptedException ignored){ }
           };
           t.start();   // <--- Here
        }

        long start = System.nanoTime();
        startGate.countDown();
        endGate.await();
        long end = System.nanoTime();
        return end - start;
    }

}
公共类TestHarness{
公共长时间任务(整数次读取,最终可运行任务){
最终倒计时闩锁开始日期=新倒计时闩锁(1);
最终倒计时闩锁结束门=新倒计时闩锁(n次读取);
对于(i=0;i

这是可能的。只是在其他线程都调用了
countDown()之前,
countDown()不会完成
同样如此。

原始版本似乎并不保证在@St.Antario所提到的启动之前所有线程都准备就绪。它确实保证在代码
long start=System.nanoTime();

一些线程可以在所有线程初始化之前开始运行。我认为如果代码希望在所有线程都准备好之前停止所有线程的启动,那么代码必须是:

public class TestHarness{

public long timeTask(int nThreads, final Runnable task){

    final CountDownLatch startGate = new CountDownLatch(nThreads);//Changed this from 1
    final CountDownLatch endGate = new CountDownLatch(nThreads);

    for(i = 0; i < nThreads; i++) {
       Thread t = new Thread(){
          try{
              startGate.countDown(); //Reduce the latch count by 1
              startGate.await(); //Once the last Thread is ready, this will continue
              try{
                  task.run();
              } finally {
                  endGate.countDown();
              }
          } catch (InterruptedException ignored){ }
       };
       t.start();   // <--- Here
    }

    long start = System.nanoTime();
    endGate.await();
    long end = System.nanoTime();
    return end - start;
  }

}

这意味着某些线程可能在startGate.countDown()之前未准备好/创建调用。

因此,这会导致示例不正确,因为辅助线程可能不会同时启动。为什么会在内部使用
Sync
?@St.Antario时对其进行重新排序,为什么会导致示例不正确?@SMA,线程实际上不必立即启动。这可以(而且通常是这样的)稍晚发生。您的意思是直到其他线程调用了
await()
startGate
endGate
在这里没有任何关系(除了逻辑关系之外),是吗?那完全是错的。请阅读
CountDownLatch
的Javadocs。啊,没有看到您增加了
startGate
的权限。是的,这也可以。但是我似乎无法删除我的否决票,因为有一些任意的时间限制,除非您编辑您的帖子。好的,编辑它以添加评论,这样对人们来说很容易查看对startGate增加的编辑。@Kayaman好的,现在我看到它工作了,但它没有解释为什么原始示例会这样做……以及为什么
import java.util.concurrent.CountDownLatch;

public class TestHarness{


    public long timeTask(int nThreads, final Runnable task) throws InterruptedException{

        final CountDownLatch startGate = new CountDownLatch(1);
        final CountDownLatch endGate = new CountDownLatch(nThreads);

        for(int i = 0; i < nThreads; i++) {
           Thread t = new Thread( new Runnable(){

            @Override
            public void run() {
                  try{
                      System.out.println("Init");
                      startGate.await();

                      try{
                          task.run();
                      } finally {
                          endGate.countDown();
                      }
                  } catch (InterruptedException ignored){ }
               };

            });

           t.start();   // <--- Here
        }
        long start = System.nanoTime();
        startGate.countDown();
        System.out.println("Open Gate");

        endGate.await();
        long end = System.nanoTime();
        return end - start;
 }

    public static void main(String[] args) throws Exception {
        new TestHarness().timeTask(10, new Runnable() {

            @Override
            public void run() {
              System.out.println("Am Running");

            }
        });
    }
}
Init
Open Gate
Am Running
Init