Hay*_*yan -2 java multithreading volatile
这是我的简单类,它在单独的线程中递增共享变量:
public class Main {
private volatile int count;
public static void main(String[] args) {
Main main = new Main();
main.doJob();
}
private void doJob() {
Runnable runnable1 = () -> {
for (int i = 0; i < 10000; i++) {
incrementCount();
}
};
Runnable runnable2 = () -> {
for (int i = 0; i < 10000; i++) {
incrementCount();
}
};
Thread t1 = new Thread(runnable1);
Thread t2 = new Thread(runnable2);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------------------ count is : " + count);
}
private void incrementCount() {
count = count + 1;
}
}
Run Code Online (Sandbox Code Playgroud)
现在任何人都可以告诉我为什么volatile关键字不能帮助我产生正确的结果,我希望它是20000?
但是,当我将方法声明更改为private syncronized void incrementCount(),一切都按预期进行时,它打印20000甚至没有volatile关键字.
小智 7
关键在于声明
count = count + 1;
Run Code Online (Sandbox Code Playgroud)
不是原子操作.因此,两个线程可以查看count变量的相同旧值,然后计算新值.甚至更多的一个线程可以在另一个线程读取和写入之间进行多个计算周期.
该volatile关键字保证可视性.
在哪里作为synchronized保证相互排他性.
这意味着当变量被标记为volatile所有线程必须访问最新值时.它没有缓存.想象一下多核/多处理器机器,每台机器都有自己的缓存.随着volatile每次线程读取它保证是最新和最伟大的变量的值.
在同一场景中,每个线程都可以更新它.
现在,在您的情况下count = count + 1,发生了多个操作.
读取值count,增加它,然后设置为变量值count.
在这一点,如果count是volatile在时间说t线程1次的更新呢,再说1.然后在t+1说线程2和线程3要更新它,挥发性保证这两个线程看到价值1.然而两者都将增加1,并把它放回去.所以你实际上失去了一个增量.
什么synchronized保证是t+1,只有其中一个线程说线程2将进入它,读取值1,将其增加到2,并将其设置回变量计数.然后线程3可以输入这个同步的代码块来读取值2,将其增加到3,并将其设置回count
| 归档时间: |
|
| 查看次数: |
62 次 |
| 最近记录: |