格言:在程序猿界混出点名堂!
《JAVA并发编程实战》解读
【连载】第3章-3.2发布与逸出
上一节思考题:用Volatile修饰的变量vi,多线程执行vi++,线程安全吗?
答案是不安全,因为volatile只能保证自身的原子性,保证不了vi++这种复合操作的原子性。
回顾:上一节聊了非原子的64位,比如long和double,然后使用volatile关键字可以保证变量的原子性,该关键字是一种稍弱的同步机制,这一节讲的是发布与逃逸。
发布与逸出
发布:使对象能够在当前作用域外的代码使用。
逃逸:当一个不该发布的对象被发布出去的时候。
什么意思呢?比如某系统的CacheService,本来缓存系统的参数列表PARAMS仅供其他方法只读访问,但是其他类获取后可以修改Param对象的内容,让缓存PARAMS失去控制。
有的时候我们也会听到方法逃逸这个关键词,也就是说方法内的局部变量从方法内逃逸出去。
@NotSafe
public class CacheService{
private static Map<String,Param> PARAMS = new HashMap<>();
static{
initParams();
}
public Map<String,Param> getParams(){
return PARAMS;
}
}
发布的方式
- 公有的静态变量
比如
public static Map<String,Param> PARAMS = new HashMap<>();
- 通过方法传递给作用域外
比如私有或者局部通过方法返回以发布出去。 - 间接发布对象
比如CacheService中的Param对象就被间接发布出去了。 - 发布内部的类实例
public class ThisEscape{
public ThisEscape(EventSource source){
source.registerListener(new EventListener(){
public void onEvent(Event e){
doSomething();
}
});
}
}
当ThisEscape发布EventListener时,也隐含地发布了ThisEscape实例本身,因为在这个内部类的实例中包含了对ThisEscape实例的隐含引用。
试想,如果在构造函数还未初始化好的时候,事件对this对象进行了修改。让this对象出现了不可控的状态。
后面章节会解说如何安全发布,可关注微信公众号,查看下期连载。
喜欢连载可关注
简书
或者微信公众号
:
简书专题:Java并发编程实战-可爱猪猪解读
https://www.jianshu.com/c/ac717321a386
微信公众号:可爱猪猪聊程序
。
网友评论