校招Java准备——volatile

volatile作用:

被volatile修饰的变量保证了可见性。

1. 当volatile修饰的变量被修改时,修改的值会立刻写入主存

2. 当变量的值被修改后,其他线程的工作内存中该变量的值会无效

 

同步三大性质,volatile都实现了吗?

原子性:没有。对volatile的复制操作不是原子性的。如果是将一个字面量赋值给变量,那本来也只需要执行一步;如果是将其他的变量 或者 加减乘除操作得到的结果赋值给变量,读取变量值以及计算的过程不是原子性的(可以看一下使用场景中的例子)

可见性:实现了

有序性:

volatile关键字能禁止指令重排序,所以volatile能在一定程度上保证有序性。

volatile关键字禁止指令重排序有两层意思:

  1)当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行;

  2)在进行指令优化时,不能将在对volatile变量访问的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执行。【引用:https://www.cnblogs.com/dolphin0520/p/3920373.html

 

使用条件 / 场景:

使用volatile首先是这个场景需要保证变量的可见性,且对变量的使用方式是原子性的:

条件1:对变量的写操作不依赖于当前值

例如【反例】: volatile  int  a = 0;    a = a + 1;

在修改a的值时,需要依赖它的当前值。而voiltile不保证原子性,因此a = a +1这个操作会被分为3部:

首先读取a 的值; 再将a与1相加; 之后将和赋值给a;  这个过程中,如果线程在进行完了第二步之后被打断,且有其它线程修改了a的值,那么当该线程继续执行时,虽然它能够发现a的值被改变了,但它之前执行的a+1操作得到的和不会变,因此它会将a+1的赋值给a;这导致了另一个线程对a的修改被覆盖了。

条件2:该变量没有包含在具有其他变量的不变式中

【这个没太明白啊,每一个博客总有不明白的地方】

场景:

double check

public class Singleton{
    private volatile static Singleton single = null;

    public Singleton getSingle(){
        if(single == null){
            synchronized(Singleton.class){
                if(single == null){
                    single = new Singleton();
                }
            }
        }

        return single; 
    }  
}

记录最近一次登录用户的信息(最近登录的用户不依赖于前一个登录的用户)

public class UserManager {
    public volatile String lastUser; //发布的信息
 
    public boolean authenticate(String user, String password) {
        boolean valid = passwordIsValid(user, password);
        if (valid) {
            User u = new User();
            activeUsers.add(u);
            lastUser = user;
        }
        return valid;
    }

引用:https://blog.csdn.net/vking_wang/article/details/9982709

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值