线程安全
什么是线程安全(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获得的锁是可重入的,也就是一个线程获得了锁之后可以再次进入这个锁。
本文介绍了线程安全的概念,探讨了如何确保类在多线程环境下能够正确地被访问,以及原子性在防止竞态条件中的作用。通过具体代码示例展示了实现线程安全的方法。
801

被折叠的 条评论
为什么被折叠?



