volatile 對於n=n+1,無效
阿新 • • 發佈:2020-08-13
1.volatile 針對b=b+1 不是原子操作的
理論上來說結果等於1000,實際上很多時候小於1000
package com.sun.util; class A { volatile int b=0; void add(int n){ for (int i = 0; i < n; i++) { b+=1; } } } public class VolatileTest { public static void main(String[] args) { A aaa= new A(); Thread[] t=new Thread[100]; for (int i = 0; i < t.length; i++) { final int x=10; t[i]=new Thread(()->aaa.add(10)); } for (int i = 0; i < t.length; i++) { t[i].start(); } for (int i = 0; i < t.length; i++) {try { t[i].join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(aaa.b); } }
2.用synchronized
package com.sun.util; class A { volatileint b=0; void add(int n){ for (int i = 0; i < n; i++) { // b+=1; inc(); } } synchronized void inc(){ b=b+1; } } public class VolatileTest { public static void main(String[] args) { A aaa = new A(); Thread[] t=new Thread[100]; for (int i = 0; i < t.length; i++) { final int x=i+1; t[i]=new Thread(()->aaa.add(x)); } for (int i = 0; i < t.length; i++) { t[i].start(); } for (int i = 0; i < t.length; i++) { try { t[i].join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(aaa.b); } }
或者
package com.sun.util; class A { volatile int b=0; synchronized void add(int n){ for (int i = 0; i < n; i++) { b+=1; // inc(); } } // synchronized void inc(){ // b=b+1; // } } public class VolatileTest { public static void main(String[] args) { A aaa = new A(); Thread[] t=new Thread[100]; for (int i = 0; i < t.length; i++) { final int x=i+1; t[i]=new Thread(()->aaa.add(x)); } for (int i = 0; i < t.length; i++) { t[i].start(); } for (int i = 0; i < t.length; i++) { try { t[i].join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(aaa.b); } }