【发布时间】:2019-02-19 03:17:56
【问题描述】:
public class VolatileDemo implements Runnable{
private static volatile int count = 0;
private Random random = new Random();
public static void main(String[] args) {
for(int i=0;i<1000;i++){
new Thread(new VolatileDemo()).start();
}
while(Thread.activeCount()>1){
Thread.yield();
}
System.out.println(count);
}
@Override
public synchronized void run() {
try {
Thread.sleep(random.nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+" " + count++);
}
}
运行后(在jdk1.8),答案不是1000,请告诉我原因。
【问题讨论】:
-
提示:尝试将该计数替换为类型
AtomicInteger并调用该对象的相应方法。看看会发生什么。 -
方法上同步意味着不能同时对同一个对象进行两次调用docs.oracle.com/javase/tutorial/essential/concurrency/…你可以尝试在for之外提取(new VolatileDemo)
-
@vmrvector。谢谢,我总是有点困惑。 @aigaoxiaode 如果你在静态对象上同步
count++行,你会得到1000。 -
@SteveSmith,他在非静态方法
run上使用了synchronized关键字。这意味着this(在他的例子中是VolatileDemo实例)将用作监视器。而且当他创建多个VolatileDemo实例时,监视器都是不同的,同步没有效果。带有private static final Object lockObject = new Object()的synchronized(lockObject) {...}块可以解决问题。AtomicInteger也可以。 -
@SteveSmith 感谢您的文档,但是如果我将活动线程的数量更改为 0,程序将永远不会停止,因为主线程仍然存在。