美文网首页
volatile线程可见性,但不能保证操作原子性

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

作者: zhaozhaoicode | 来源:发表于2020-05-07 00:31 被阅读0次

    volatile特性

    • 保证线程可见性 MESI缓存一致性协议
    • 禁止指令重排序

    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修改字节码模拟

    相关文章

      网友评论

          本文标题:volatile线程可见性,但不能保证操作原子性

          本文链接:https://www.haomeiwen.com/subject/rypnghtx.html