正确使用volatile

来源:互联网 发布:淘宝评价模版 编辑:程序博客网 时间:2024/05/18 02:46

volatile仅仅能保证变量可见性, 无法保证原子性.


如n=n+1、n++等,volatile关键字将失效

1.volatile可用于状态标志.boolean类型


2.一次性发布


public class BackgroundFloobleLoader {    public volatile Flooble theFlooble; //此处构造时调用一次    public void initInBackground() {        // do lots of stuff        theFlooble = new Flooble();  // this is the only write to theFlooble    }}public class SomeOtherClass {    public void doWork() {        while (true) {             // do some stuff...            // use the Flooble, but only if it is ready            if (floobleLoader.theFlooble != null)                 doSomething(floobleLoader.theFlooble);        }    }}
必要条件是:被发布的对象必须是线程安全的,或者是有效的不可变对象(有效不可变意味着对象的状态在发布之后不会被修改)。
3.独立观察
代码展示了身份验证机制如何记忆最近一次登录的用户的名字。将反复使用 lastUser 引用来发布值,以供程序的其他部分使用
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;    }} 
某个值发布以在程序内的其他地方使用,但是与一次性事件的发布不同,这是一系列独立事件。这个模式要求被发布的值是有效不可变的 —— 即值的状态在发布后不会更改。
5.volatile
@ThreadSafepublic class Person {    private volatile String firstName;    private volatile String lastName;    private volatile int age;    public String getFirstName() { return firstName; }    public String getLastName() { return lastName; }    public int getAge() { return age; }    public void setFirstName(String firstName) {         this.firstName = firstName;    }    public void setLastName(String lastName) {         this.lastName = lastName;    }    public void setAge(int age) {         this.age = age;    }}

JavaBean 的所有数据成员都是 volatile 类型的,并且 getter 和 setter 方法必须非常普通 —— 除了获取或设置相应的属性外,不能包含任何逻辑。
很多框架为易变数据的持有者(例如 HttpSession)提供了容器


6.开销较低读写策略

读多写少场景

@ThreadSafepublic class CheesyCounter {      @GuardedBy("this") private volatile int value;    public int getValue() { return value; }    public synchronized int increment() {        return value++;    }}


原创粉丝点击