第三章 对象的共享(三)

前言:前面我们讲了线程封闭技术(确保对象不被发布)和发布不可变对象。


3.5 安全发布

在某些情况下,我们希望在多个线程间共享对象,此时必须确保进行安全的共享。


3.5.3 安全发布的常用模式

要安全的发布一个对象,对象的引用以及对象的状态必须同时对其他线程可见。一个正确构造的对象可以通过以下方式安全的发布:

(1)在静态初始化函数中初始化一个对象引用。

(2)将对象的引用保存到volatile类型的域或者AtomicReference对象中。

(3)将对象的引用保存到某个正确构造对象的final类型域中。

(4)将对象的引用保存到一个由锁保护的域中。


3.5.4 事实不可变对象

如果对象在技术上看来是可变的,但其状态在发布后不会再改变,那么把这种对象称作“事实不可变对象”。

在没有任何额外的同步情况下,任何线程都可以安全地使用被安全发布的事实不可变对象。

例如,Date 本身是可变的,但如果将它作为不可变对象来使用,那么在多个线程间共享Date对象时,就可以省去对锁的使用。假设需要维护一个map,其中保存了每位用户的最近登陆时间:

public Map<String,Date> lastLogin =Collections.synchronizedMap(new HashMap<String,Date>);

如果Date 对象的值在被放入Map后就不会改变,那么synchronizedMap中的同步机制就足以使Date值被安全的发布,并且在访问这些Date值时不需要额外的同步。

对象的发布需求取决于它的可变性:

(1)不可变对象可以通过任意机制发布。

(2)事实不可变对象必须通过安全方式来发布。

(3)可变对象必须通过安全方式发布,并且必须是线程安全的或者由某个锁保护起来。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容