Java之Volatile轻量级同步使用

2018-06-02  本文已影响0人  离别刀

volatile关键字有两个特性

private int a;
private int b;
在线程A中有两条语句对这两个共享变量进行赋值操作:
a = 1;
b = 2;
假设当线程A对a进行复制操作的时候发现这个变量在主内存已经被其它的线程加了访问锁,那么此时线程A怎么办?等待释放锁?不,等待太浪费时间了,它会去尝试进行b的赋值操作,b这时候没被人占用,因此就会先为b赋值,再去为a赋值,那么执行的顺序就变成了:
b = 2;
a = 1;
而Volatile关键字就能阻止这种指令重新排序,确保并发时程序执行顺序的正确性。

关键字Volatitle是java提供的一种轻量级的同步机制,当一个变量被Volatile修饰之后,它有以下特殊的访问规则如下
线程可见性,当Volatile修饰的变量被某个线程修改之后,无论该变量是否加锁,其它的线程都可以立即看到该变量的最新值,普通变量是不行的。
如下图示例

public class VolatileTest {
    public volatile boolean stop=false;

    public  String out="step one...........";

    public void run() throws InterruptedException {
        Thread thread1= new Thread(new Runnable() {
            @Override public void run() {
                while(!stop){
                    System.out.println(Thread.currentThread().getName()+out);
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        Thread thread2= new Thread(new Runnable() {
            @Override public void run() {
                while(!stop){
                    System.out.println(Thread.currentThread().getName()+out);
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        thread1.start();
        thread2.start();
    }

    public static void main(String[] args) throws InterruptedException {
        VolatileTest test= new VolatileTest();
        test.run();
        TimeUnit.SECONDS.sleep(2);
        test.stop=true;
    }
}

运行结果:
Thread-1step one...........
Thread-0step one...........
Thread-1step one...........
Thread-0step one...........

总结:Volatile适用于一个线程写,多个线程读的情况,某些场景用它替换Synchronized并发访问会大大提高。

上一篇下一篇

猜你喜欢

热点阅读