美文网首页
JAVA_volatile

JAVA_volatile

作者: Shokka | 来源:发表于2018-08-21 11:52 被阅读0次

    https://www.cnblogs.com/dolphin0520/p/3920373.html

    当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。
    而普通的共享变量不能保证可见性,因为普通共享变量被修改之后,什么时候被写入主存是不确定的,当其他线程去读取时,此时内存中可能还是原来的旧值,因此无法保证可见性。

    volatile作用
    一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:

    1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

    2)禁止进行指令重排序。

    重点
    无法保证原子性,可以保证有序性,(可见性 报有疑问,希望高手指点)
    个人理解:
    一开始从无法保证原子性这一点出发,让我怀疑volatile到底能不能保证可见性,因为A线程的读写操作只进行到读,cpu就转而执行B线程的写操作,而当重新执行A线程的第二部写操作时,B线程之前所做的写操作就会被覆盖,出现了脏数据。
    如果说保证可见性,那么B线程执行写操作后A线程就应该重新获取一次变量值,这才是真正的可见性。

    package org.kevin.lucene;
    
    public class VolatileTest {
    
        private static volatile String string = "";
        
    //  public int get() {
    //      return num;
    //  }
    //  
    //  public void selfAdd() {
    //      num++;
    //  }
    //  
        public static void main(String[] args) throws InterruptedException {
            
            
        
            Thread t1 = new Thread("thread A") {
                public void run() {
                    System.out.println("start "+this.getName());
                    for(int i = 0 ; i < 50 ; i++ ) {
                        //read
                        System.out.println(this.getName()+":read -> "+string);
                        //write
                        string = "A"+i;
                        System.out.println(this.getName()+":write -> "+string);
                    }
                        
                }
            };
            
            Thread t2 = new Thread("thread B") {
                public void run() {
                    System.out.println("start "+this.getName());
                    for(int i = 0 ; i < 50 ; i++ ) {
                        //read
                        System.out.println(this.getName()+":read ->"+string);
                        //write
                        string = "B"+i;
                        System.out.println(this.getName()+":write -> "+string);
                    }
                }
            };
            
            t1.start();
            t2.start();
            
            t1.join();
            t2.join();
        }
    
    }
    
    

    输出:脏,我写出来的多线程真的贼赃

    start thread B
    thread B:read ->
    start thread A
    thread B:write -> B0
    thread B:read ->B0
    thread B:write -> B1
    thread B:read ->B1
    thread B:write -> B2
    thread B:read ->B2
    thread B:write -> B3
    thread B:read ->B3
    thread B:write -> B4
    thread B:read ->B4
    thread A:read -> B0
    thread B:write -> B5
    thread B:read ->A0
    thread B:write -> B6
    thread B:read ->B6
    thread B:write -> B7
    thread B:read ->B7
    thread A:write -> A0
    thread A:read -> B8
    thread B:write -> B8
    thread B:read ->A1
    thread A:write -> A1
    thread B:write -> B9
    thread B:read ->B9
    thread B:write -> B10
    thread B:read ->B10
    thread B:write -> B11
    thread B:read ->B11
    thread B:write -> B12
    thread B:read ->B12
    thread B:write -> B13
    thread B:read ->B13
    thread B:write -> B14
    thread B:read ->B14
    thread B:write -> B15
    thread B:read ->B15
    thread B:write -> B16
    thread B:read ->B16
    thread B:write -> B17
    thread B:read ->B17
    thread B:write -> B18...
    

    所以说我并不同意volatile保证了可见性这一说法,我只同意他保证了有序性。因为他能保证可见性是在原子性的前提下。

    相关文章

      网友评论

          本文标题:JAVA_volatile

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