Thread Confinement
如果数据只被一个线程访问,那自然就不需要同步。所以Thread Confinement是获得线程安全最简单的方式之一。这有几种方式。可以完全依赖于实现,也就是调用者来保证只有单线程访问,但这有可能不是很安全。所以还有其它办法来实现这一点。
Stack Confinement
局部变量必然是线程安全的,只要它们没有escape。局部变量存在于当前线程的栈中,是不能被其它线程所访问的。
ThreadLocal
更正式一些的方式是使用ThreadLocal对象。可以把ThreadLocal看成是每个线程所拥有的一个Map。注意不要滥用ThreadLocal,要慎用,以免影响系统复用性,增加类之间的耦合等等带来不良的设计味道。
Immutability
也可以使用immutable对象来避免同步。immutable对象是指那些在构造完成之后状态就不会改变的对象。Immutable对象总是线程安全的。
An object is immutable if:
- Its state cannot be modifled after construction;
- All its flelds are final ;
- It is properly constructed (the this reference does not escape during construction).
为什么所有field都要求是final的?当然也不一定必须都是final的,比如String。但如果不是final的,会有什么问题,是因为可以继承这个类,然后再修改父类的状态?
安全发布
Improper Publication是很危险的。对于还没有完全构造好就发布的对象而言,可能线程会看到这个对象不一致的状态。
对于Immutable对象,java内存模型提供了一种机制保证共享Immutable对象时的Initialization safety。“Immutable objects can be used safely by any thread without additional synchronization, even when synchronization is not used to publish them.”
要安全发布对象,对象的引用和对象本身的状态必须同时都对其它线程是可见的。安全发布的几种方式:
- Initializing an object reference from a static initializer;
- Storing a reference to it into a volatile field or AtomicReference ;
- Storing a reference to it into a final field of a properly constructed object; or
- Storing a reference to it into a field that is properly guarded by a lock.
使用static initializer是最简单的方式。
对于非technically immutable,但状态在publication后不会被改变的对象,我们称之为Effectively Immutable。这种对象只要安全发布就可以了,不需要额外的同步。
- Immutable objects can be published through any mechanism;
- Effectively immutable objects must be safely published;
- Mutable objects must be safely published, and must be either threadsafe or guarded by a lock.
安全的共享对象:当你发布一个对象的时候,应该说明这个对象能够如何被访问。下面是最有用的几种policy:
- Thread-confined. 排他性的属于某个线程,并且可被这个线程修改
- Shared read-only. 能够并发的多线程访问而无需同步, 但不能被任何线程修改。这包括immutable和effectively immutable对象。
- Shared thread-safe. 在内部同步, 所以多线程访问时不需同步
- Guarded. 只能通过特定的锁来访问. Guarded objects include those that are encapsulated within other thread-safe objects and published objects that are known to be guarded by a specific lock.
安全发布这一节没太看明白。需要以后回过头来再读几遍。