1_基础知识_chapter03_对象的共享_5_安全发布

  • (1) Java内存模型为不可变对象的共享提供了特殊的初始化安全性保证, 即使在发布这些对象时没有同步

    (2) 在没有额外同步的情况下, 也可以保证安全访问final类型的域(但是如果final类型的域所指向的是可变对象, 还是需要同步)

  • 一个正确构造的对象, 可以通过以下方式安全发布

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

    JVM内部存在的同步机制保证

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

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

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

    (将对象放入到某个带锁的容器例如Vector, synchronizedList再发布也属于这种情形)

    所有的安全发布机制都能确保, 当对象的引用对所有访问该对象的线程可见时, 对象发布时的状态对于所有线程也将是可见的。如果对象状态不再改变, 那么足以确保任何访问都是安全的

  • 事实不可变对象

    (1) 如果对象从技术上看可变, 但是其状态从发布后不会再改变, 则这种对象称为事实不可变对象(例如java.util.Date类)

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

  • 可变对象

    不仅在发布时需要使用同步, 每次对象访问时也要使用同步来确保后续修改操作的可见性

    示例

      public class Holder {
    
          private int n;
    
          public Holder(int n) {
    
              this.n = n;
          }
    
          public void assertSanity() {
    
              if (n != n) {
                  throw new AssertionError("This statement is false.");
              }
          }
      }
    

    在多线程环境下, Holder很可能没有被正确发布, 造成某个线程中未必看到其他线程构造好的n的值, 从而造成AssertionError; 如果将n用final修饰, 则可以避免这个问题

  • 对象的发布需求

    不可变对象: 任意机制发布

    事实不可变对象: 安全发布方式(4种)

    可变对象: 由某个锁保护发布

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值