可见性
当一个线程修改了对象状态后,其他线程能够看到发生的状态变化
如何保证?
- 加锁,当线程B执行由锁保护的同步代码块时,可以看到线程A在同一个同步代码块中的所有操作结果。(这也是为什么要求访问某个共享且可变的变量时要求所有线程在同一个锁上同步)
- vlolatile变量,确保将变量的更新操作通知到其他线程。(不会被重排序,不会被缓存)
原子性
操作不会被线程调度器打断
如何保证?
- synchronized,同时保证了可见性与原子性
不变性
如果某个对象在构造后状态不再改变,那么这个对象就是不可变对象,一定是线程安全的
要求
- 对象创建后状态不可更改
对象所有域都是final类型(意义上的,而非一定都是final关键字标记) - 对象正确创建,创建期间this引用没有溢出
关于逸出的问题
例如构造方法中发布了一个内部类,由于内部类实例包含了对外部类实例的隐含引用,导致创建期间外部类实例的this逸出
如果安全的发布?
- 静态初始化函数中初始化一个对象引用(public static MyObj obj=new MyObj())
- 将对象引用保存在violatile类型或者AtomicReference对象中
- 将对象引用保存在某个正确构造对象的final域中
- 将对象引用保存在由锁保护的域中,如线程安全容器vector,hashtable