volatile线程可见性,但不能保证操作原子性

2020-05-07  本文已影响0人  zhaozhaoicode

volatile特性

volatile线程可见性,但不能保证操作原子性

import java.util.ArrayList;
import java.util.List;

public class TestVolatileNotSync {
    
    volatile int count = 0;
    void m() {
        for(int i=0; i<10000; i++) count++;
    }
    
    public static void main(String[] args) {
        TestVolatileNotSync t = new TestVolatileNotSync();
        
        List<Thread> threads = new ArrayList<Thread>();
        
        for(int i=0; i<10; i++) {
            threads.add(new Thread(t::m, "thread-"+i));
        }
        
        threads.forEach(Thread::start);
        
        threads.forEach((o)->{
            try {
                o.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println(t.count);
    }
}

输入结果:58155

多次运行到达不了100000,volatile并不能保证多个线程共同修改i变量时所带来的不一致问题,也就是说volatile不能替代synchronized。

import java.util.ArrayList;
import java.util.List;


public class TestVolatileSync {
    /*volatile*/ int count = 0;

    synchronized void m() { 
        for (int i = 0; i < 10000; i++)
            count++;
    }

    public static void main(String[] args) {
        TestVolatileSync t = new TestVolatileSync();

        List<Thread> threads = new ArrayList<Thread>();

        for (int i = 0; i < 10; i++) {
            threads.add(new Thread(t::m, "thread-" + i));
        }

        threads.forEach((o) -> o.start());

        threads.forEach((o) -> {
            try {
                o.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        System.out.println(t.count);

    }

}

输入结果:100000

指令重排序不好模拟,据说可以使用asm修改字节码模拟

上一篇下一篇

猜你喜欢

热点阅读