关于volatile在并发编程中的实际作用

原因:并发编程中,由于cpu在主内存中运行的,而线程是在工作内存中执行,线程中修改共享变量的值修改的是工作内存中的变量,需要重新写入主内存中,其他线程才能够读取修改后的共享变量。

关于并发编程中的三个概念:

原子性,可见性,有序性。

valatile修饰的变量可以让代码块具备可见性和有序性,但是不具备原子性,线程中只有最简单单一的读写操作才具备原子性,如果同时具备读写修改则不具备原子性。

valatile用途:

用来判断线程的执行标志,修饰单例模式的单例类对象,进行double check。

valatile无原子性的解决办法:

synchronize:

public class Test {
    public  int inc = 0;
    
    public synchronized void increase() {
        inc++;
    }
    
    public static void main(String[] args) {
        final Test test = new Test();
        for(int i=0;i<10;i++){
            new Thread(){
                public void run() {
                    for(int j=0;j<1000;j++)
                        test.increase();
                };
            }.start();
        }
        
        while(Thread.activeCount()>1)  //保证前面的线程都执行完
            Thread.yield();
        System.out.println(test.inc);
    }
}

 

lock:

public class Test {
    public  int inc = 0;
    Lock lock = new ReentrantLock();
    
    public  void increase() {
        lock.lock();
        try {
            inc++;
        } finally{
            lock.unlock();
        }
    }
    
    public static void main(String[] args) {
        final Test test = new Test();
        for(int i=0;i<10;i++){
            new Thread(){
                public void run() {
                    for(int j=0;j<1000;j++)
                        test.increase();
                };
            }.start();
        }
        
        while(Thread.activeCount()>1)  //保证前面的线程都执行完
            Thread.yield();
        System.out.println(test.inc);
    }
}

AtomicInteger:

public class Test {
    public  AtomicInteger inc = new AtomicInteger();
     
    public  void increase() {
        inc.getAndIncrement();
    }
    
    public static void main(String[] args) {
        final Test test = new Test();
        for(int i=0;i<10;i++){
            new Thread(){
                public void run() {
                    for(int j=0;j<1000;j++)
                        test.increase();
                };
            }.start();
        }
        
        while(Thread.activeCount()>1)  //保证前面的线程都执行完
            Thread.yield();
        System.out.println(test.inc);
    }
}

 

posted @ 2019-09-25 20:12  灰太狼&红太狼  阅读(308)  评论(0)    收藏  举报