第二章 线程安全性
- 对象的状态:存储在状态变量(实例或者静态域)中的数据。
- 共享:变量可以被多个线程同时访问。
- 可变:变量的值在其生命周期内可以发生变化。
- 线程安全:多个线程访问某个类的时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的。
- 实现线程安全:
1.不在线程之间共享变量的状态 - 不共享
2.将状态变量修改为不可变的变量 - 不可变
3.在访问状态变量时使用同步 - 同步 - 同步机制包含:
1.synchronized
2.volatile
3.显式锁
4.原子变量 - 竞态条件:不恰当的执行时序出现不正确的结果。
- 不变性条件。验证程序是否满足最基本的正确性。
- 要保持状态的一致性,就需要在单个原子操作中更新所有相关的状态变量。
- 重入:一个线程请求其他线程持有的锁会失败,请求本线程持有的锁会成功。synchronized和reentrantLock都是可重入的。
- 活跃性和性能问题:降低锁粒度
第三章 对象的共享
- 可见性:一个线程对变量的修改,其他线程不一定能访问到改修改。需要对变量做同步才可以保证可见。
- 在没有同步的情况下,编译器、处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整。在缺乏足够同步的多线程程序中,要想对内存操作得当执行顺序进行判断,几乎无法得出正确的结论。 个人总结:编译器会进行优化,指令重排序等,需要设置内存屏障来保证必要的指令不会被重排序。java中有一堆happends before规则。
- 只要有数据在多个线程之间共享,就使用正确的同步。
- 失效数据:没有使用正确的同步的情况下,一个线性没有读到其他线程对变量的修改。
- 64位变量和最低安全性:最低安全性:虽然读到的变量值可能会失效,但是确实是其他线程设置过得。long这些可能读到不同版本的高32位和低32位。
- 发布:是对象能够在当前作用域之外的代码中使用。
- 逸出:某个不应该发布的对象被发布。
- ThisEscape:this指针逃逸,在构造函数调用外部方法,或者起一个线程之类的。
- 线程封闭:不共享可变数据。threadlocal。
- 栈封闭:局部变量。
- 不变性:不可变对象,Immutable Object。
1.对象创建之后状态不可修改
2.所有的域都是final
3.对象是正确创建的。 - Final域:final字段不可修改,但是final字段如果是引用类型,引用的对象的状态是可以修改的。java内存模型中,final有特殊的语义,final能保初始化过程的安全性。。。不太理解
java 封装的一个院子操作:unsafe.compareAndSwapInt
网友评论