Java 了解启动线程和可能涉及的数据竞争
我正在阅读B.Goetz 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
锁存器
描述为一种同步器,并提供了倒计时锁存器
的典型用例:
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