这段代码不仅仅受到重排序的困扰,即使1、2没有重排序。3也不会那么顺利的履行的。假设照样线程1先履行write操作,线程2再履行multiply操作,因为线程1是在工作内存里把flag赋值为1,不必定急速写回主存,所以线程2履行时,multiply再大年夜主存读flag值,仍然可能为false,那么括号里的语句将不会履行。 如不雅改成下面如许:
- int a = 0;
- volatile bool flag = false;
- public void write() {
- a = 2; //1
- flag = true; //2
- }
- public void multiply() {
- if (flag) { //3
- int ret = a * a;//4
- }
- }
那么线程1先履行write,线程2再履行multiply。根据happens-before原则,这个过程会知足以下3类规矩: 法度榜样次序规矩:1 happens-before 2; 3 happens-before 4; (volatile限制了指令重排序,所以1 在2 之前履行) volatile规矩:2 happens-before 3 传递性规矩:1 happens-before 4 当写一个volatile变量时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存 当读一个volatile变量时,JMM会把该线程对应的本地内存置为无效,线程接下来将大年夜主内存中攫取共享变量。
起首我答复是不克不及包管原子性,如果说能包管,也执偾对单个volatile变量的读/写具有原子性,然则对于类似volatile++如许的复合操作就力所不及了,比如下面的例子:
- public class Test {
- public volatile int inc = 0;
- public void increase() {
- inc++;
- }
- public static void main(String[] args) {
- final Test test = new Test();
- for(int i=0;i<10;i++){
- new Thread(){
- public void run() {
- for(int j=0;j<1000;j++)
- test.increase();
- };
- }.start();
- }
- while(Thread.activeCount()>1) //包管前面的线程都履行完
- Thread.yield();
推荐阅读
年前最后一场技巧盛宴 | 1月27日与京东、日记易技巧大年夜咖畅聊智能化运维成长趋势! ELF Binary Image Mapped Into MemoryKernel/User Memory Split内存治理是操作体系的核心义务;它对法>>>详细阅读
地址:http://www.17bianji.com/lsqh/40382.html
1/2 1