Java并发编程实战(2)

▲内存可见性:我们希望确保当一个线程修改了对象状态后,其他线程可以看到发生的状态变化。

▲不要假设指令执行的顺序,你无法预知不同线程之间的指令会以何种顺序执行。

▲一个线程可能获得某个变量的最新值,而获得另一个变量的失效值。

▲最低安全性:当线程在没有同步的情况下读取变量时,可能会得到一个失效值,但至少这个值是由之前某个线程设置的值,而不是一个随机值。

▲对于非volatile类型的long和double变量,JVM运行将64位的读操作或写操作分解成两个32位的操作。可能一个线程读到高32位,一个读到低32位。

▲在访问某个共享且可变的变量时要求所有线程在同一个锁上同步,就是为了确保某个线程写入该变量的值对于其他线程来说是可见的。

▲加锁:互斥,内存可见性。

▲volatile:①不会将在volatile变量上的操作与其他内存操作一起重排序②volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile变量时总会返回最新写入的值。

▲在访问volatile变量时不会执行加锁操作,因此也就不会执行线程阻塞。

▲从内存可见性的角度来看,写入volatile变量相当于退出同步代码块,读取volatile变量相当于进入同步代码块。

▲加锁机制既可以确保可见性又可以确保原子性,而volatile变量只能确保可见性。

▲volatile修饰long和double类型的变量使得它们拥有了简单的赋值与返回操作的原子性。

▲发布:使对象能在当前作用域之外的代码中使用。逸出:当某个不应该发布的对象被发布。

▲当发布一个对象时,在该对象的非私有域中引用的所有对象同样会被发布。

▲当把一个对象传递给某个外部方法时,就相当于发布了这个对象。

▲this引用逸出:从对象的构造函数中发布对象,这个对象是尚未构造完成的。

▲ThreadLocal:为每个使用变量的线程都存一份独立的副本。线程终止后,这些值会作为垃圾回收。

▲不可变对象:对象在创建后其状态就不能被修改。不可变对象一定是线程安全的。

▲安全发布的方式:
①在静态初始化函数中初始化一个对象引用。
②将对象的引用保存到volatile类型的域或者AtomicReference对象中。
③将对象的引用保存到某个正确构造对象的final类型域中。
④将对象的引用保存到一个由锁保护的域中。

▲静态初始化由JVM在类的初始化阶段执行,由于在JVM内部存在着同步机制,因此通过这种方式初始化的任何对象都可以被安全地发布。

▲对象的发布需求取决于它的可变性:
①不可变对象可以通过任意机制来发布。
②事实不可变对象必须通过安全方式来发布。
③可变对象必须通过安全方式来发布,并且是线程安全的或者由某个锁保护起来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值