1. 程式人生 > 實用技巧 >volatile 對於n=n+1,無效

volatile 對於n=n+1,無效

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 {
    volatile
int 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);

    }
}