线程安全
什么是线程安全(thread-safe)?
一个类,如果能够在多线程并发访问的环境下(不管线程访问的顺序)正确表现自己的行为,并且无需外部调用添加任何同步之类的操作,这个类就是线程安全的。
这个正确性可以这么理解,就是说多线程访问的结果不会不同于单线程的访问。
线程安全的类不需要外部调用提供任何附加的同步。
无状态(stateless)的类永远是线程安全的。
什么是无状态的类?没有实例变量(field),也没有引用其它类的field。
原子性
A race condition occurs when the correctness of a computation depends on the relative timing or interleaving of multiple threads by the runtime; in other words, when getting the right answer relies on lucky timing.
最常见的race condition是check-and-act。要防止这种race condition,我们需要原子性的操作。什么是原子性呢,就是说,你这个操作在执行的过程中,对于你操作的状态上其它的操作(包括你自己)要么全都执行完了,要么还没开始。
想说句通顺的中国话怎么这么难啊,还是给出原文吧:
Operations A and B are atomic with respect to each other if, from the perspective of a thread executing A, when another thread executes B, either all of B has executed or none of it has. An atomic operation is one that is atomic with respect to all operations, including itself, that operate on the same state.
来个例子
@NotThreadSafe public class UnsafeCountingFactorizer implements Servlet { private long count = 0; public long getCount() { return count; } public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); BigInteger[] factors = factor(i); ++count; encodeIntoResponse(resp, factors); } }
@ThreadSafe public class CountingFactorizer implements Servlet { private final AtomicLong count = new AtomicLong(0); public long getCount() { return count.get(); } public void service(ServletRequest req, ServletResponse resp) { BigInteger i = extractFromRequest(req); BigInteger[] factors = factor(i); count.incrementAndGet(); encodeIntoResponse(resp, factors); } }
锁
Intrinsic Locks
就是synchronized啦,每个java对象都可以作为一个锁,这个叫做intrinsic locks或者是monitor locks
synchronized (lock) { // Access or modify shared state guarded by lock }
Reentancy
synchroinzed获得的锁是可重入的,也就是一个线程获得了锁之后可以再次进入这个锁。