【学习笔记-并发编程实战】第3章 对象的共享

可见性

一个共享变量被一个线程修改后,另外一个线程能够正确的获取到共享变量最新值,此共享变量具有可见性。

失效数据

缺乏同步的共享变量,在多线程访问中,就可能获取到失效数据,从而导致不可预见的错误。

非原子的64位操作

正常情况下,即使是非同步变量,不同线程获取到的不是最新数据,为失效数据,但至少它是之前存在过的值,这个值曾经出现过,这种就是所谓的最低安全性。jvm将非volatile类型的long和double变量(64位数值)分解为两个32位操作,多个线程修改变量后,可能读取到不是一个值的高32位和低32位。

加锁与可见性

所有执行读操作和写操作的线程都在同一个锁上同步,保证了单个线程在修改某变量时对其他线程可见。加锁机制既可以保证可见性,又可以保证原子性。

Volatile变量

将变量的通知同步到其他线程,但是不要过度依赖此关键字提供的可见性,避免在需要对可见性执行复杂判断的地方使用(依赖变量当前的值),典型用法是检查某个状态标志是否退出循环。

 

发布与逸出

发布是使一个对象能够在当前作用域之外的代码中使用,逸出指发布了不该发布的对象,说白了就是错误的发布,导致某对象能够在指定的作用域之外的地方使用。

安全的对象构造过程(有点乱)

不要在构造函数中使this逸出,这一点还不好用文字描述,大概来说在对象构造完成之前(构造函数中),调用了this对象的方法,就上书中调用了doSomething()一样,此方法属于成员方法。另外使用匿名内部类就可以了在这个内部类中包含了ThisEscape的引用,this.doSomething(),从而导致this的方法在外部可以访问。

可以参考:https://segmentfault.com/q/1010000007900854/a-1020000018104804

线程封闭

数据共享会有安全问题,那么让数据不进行共享,只能单线程访问,则可以保证数据的安全,将变量封闭在线程内部,就是这个意思。

Ad-hoc线程封闭

维护线程封闭的职责由程序来承担,使用单线程访问共享变量,由于是单线程访问,所以。

栈封闭

局部变量就是被封闭在线程内部的,如果是一个基本数据类型,那么它肯定是线程安全的,如果是引用类型,则需要确保这个引用是被封闭在局部变量中的。

ThreadLocal类

将变量保存在Thread中,封闭在每个线程内部,确保其他线程无法访问。

 

不变性

对象的状态在确定之后无法修改,成为不可变对象,对象的状态不可变后,当时是线程安全的。要确保对象不可变,有三个必要条件:1、所有的域都使用final修饰2、正确的构造对象,保证this引用没有逸出3、对象创建以后状态就不可改变

Final域

final类型的域是不可修改的。另,变量声明时除非需要更大的作用域,否则都应该声明为私有域,除非变量时可变的对象,否则都应该使用final修饰声明为不可变对象。

使用volatile类型来发布不可变对象

由于是不可变对象,所以在更新状态的时候,需要重新创建不可变对象,这时使用volatile来保证线程能够看到最新的状态。

 

安全发布

多个线程安全的共享变量

不正确的发布:正确的对象被破坏(暂时理解不透彻)

Holder不是一个不可变对象,它的成员变量没有使用同步,导致多个线程都可以不安全的访问。书上说如果使用fianl修饰Holder中的n就可以解决安全发布的问题,大概意识就是说就变为不可变对象。

不可变对象与初始化安全性

直接上书上的结论吧,任何线程都可以在不需要额外同步的情况下安全地访问不可变对象,即使在发布这些对象时没有使用同步。

安全发布的常用模式(暂时理解不透彻)

对象的引用和对象的状态必须同时对其他线程可见,才是可变对象的安全发布:

使用静态初始化函数初始化一个对象的引用,静态初始化,只会在类加载的时候执行一次,所以。

将对象引用的域保存到volatile域或者AtomicReference对象中。

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

将对象引用保存在有锁保护的一个域中。

事实不可变对象

可变对象在构造出来之后,没有改变的需求,形成事实上的不可变对象

可变对象

不仅需要安全的发布,状态的修改也需要保证其的安全性。使用同步机制。

安全的共享对象

发布的对象所具有的正确的访问方式,通过公有接口,或者特定的锁等。

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值