java之线程安全
线程安全的四种策略
一般原则是:并发程序的正确性不应取决于时序的偶然性。
为了实现这一正确性,我们列举了实现并发代码安全的四种策略:
- 监禁不要在线程之间共享数据,通过保持变量和它们指向的数据只能从一个线程访问。
- 不变性通过使用最终变量和不可变类型,使共享数据不可变。
- 使用现有的线程安全数据类型使用为您进行协调的数据类型。
- 同步:防止线程同时访问共享数据。这是我们用来实现线程安全类型的,但是我们当时没有讨论。
死锁
当并发模块等待彼此执行某些操作时会发生死锁。死锁可能涉及两个以上的模块:死锁的信号特征是一个依赖循环,例如A正在等待等待C的等待A的B,它们都没有进展。
死锁解决方案1:锁定顺序
防止死锁的一种方法是对需要同时获取的锁定进行排序,并确保所有代码按该顺序获取锁定。
死锁解决方案2:粗粒度锁定
以注释的形式撰写线程安全策略
/** GapBuffer is a non-threadsafe EditBuffer that is optimized
* for editing with a cursor, which tends to make a sequence of
* inserts and deletes at the same place in the buffer. */
public class GapBuffer implements EditBuffer {
private char[] a;
private int gapStart;
private int gapLength;
// Rep invariant:
// 0 <= gapStart <= a.length
// 0 <= gapLength <= a.length - gapStart
// Abstraction function:
// represents the sequence a[0],...,a[gapStart-1],
// a[gapStart+gapLength],...,a[length-1]
/** SimpleBuffer is a threadsafe EditBuffer with a simple rep. */
public class SimpleBuffer implements EditBuffer {
private String text;
// Rep invariant:
// true
// Abstraction function:
// represents the sequence text[0],...,text[text.length()-1]
// Safety from rep exposure:
// text is private and immutable
// Thread safety argument:
// all accesses to text happen within SimpleBuffer methods,
// which are all guarded by SimpleBuffer's lock