Fin*_*arr -2 java concurrency volatile
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
public class Main implements Runnable {
private final CountDownLatch cdl1 = new CountDownLatch(NUM_THREADS);
private volatile int bar = 0;
private AtomicInteger count = new AtomicInteger(0);
private static final int NUM_THREADS = 25;
public static void main(String[] args) {
Main main = new Main();
for(int i = 0; i < NUM_THREADS; i++)
new Thread(main).start();
}
public void run() {
int i = count.incrementAndGet();
cdl1.countDown();
try {
cdl1.await();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
bar = i;
if(bar != i)
System.out.println("Bar not equal to i");
else
System.out.println("Bar equal to i");
}
}
Run Code Online (Sandbox Code Playgroud)
每个Thread进入run方法并通过从被调用者获取值来获取唯一的线程限制int变量.然后每个等待被叫(当最后到达闩锁时,所有被释放).释放锁存器时,每个线程都会尝试将其受限值分配给共享的,被调用的.iAtomicIntegercountThreadCountDownLatchcdl1ThreadThreadsivolatileintbar
我希望Thread除了一个之外的每一个都打印出"Bar not equal to i",但每个都Thread打印出"Bar等于i".呃,wtf确实volatile会这样做,如果不是这样的话?
这是故意的意图,每个人都Thread试图bar在完全相同的时间设置值.
编辑:
根据答案,将代码更改为:
...
bar = i;
try {
Thread.sleep(0);
} catch(InterruptedException e) {
e.printStackTrace();
}
...
Run Code Online (Sandbox Code Playgroud)
确保在设置和读取变量之间浪费一点时间.
现在,Bar的相同/不同值的打印为50/50.
JVM决定线程何时运行,而不是你.如果它感觉像握着其中一个闩锁刚刚释放了10ms的那个,那只是因为它可以做到这一点.在闩锁释放后,他们仍然需要等待轮到他们执行.除非你在一台25核计算机上运行它,否则它们并不是在机器内"同时"附近的任何地方分配条形码.由于您所做的只是一些原始操作,因此在下一个释放之前,其中一个不可能在其时间片内完成!
| 归档时间: |
|
| 查看次数: |
1850 次 |
| 最近记录: |