线程安全
ADT或方法在多线程中要正确执行
- 不违反spec、保持RI
- 不需要在spec中进行线程安全限制
保护线程安全地方法
-
限制数据共享
线程之间不共享mutable类型数据
避免使用全局变量 -
共享不可变数据
使用不可变类型数据和不可变引用
允许全局变量但必须是immutable -
共享线程安全地可变数据
查看JDK文档,文档中明确指明是否线程安全
List、Map、Set类都是线程不安全的
可以使用同步包装器,如:
Collections.synchronizedList(new ArrayList<>())
Collections.synchronizedMap(new HashMap<>()) -
同步机制:加锁
每个对象都有相关联的锁 Object lock =new Object()
拥有锁的线程可以独占式地执行该部分代码
synchronized (lock){
…
…
}
若想要互斥则要用同一把锁,同一个时刻只有一个线程可以访问该段代码
synchronized还可修饰方法、静态方法
会给程序性能带来极大影响,不建议使用
死锁
多个程序竞争lock,相互等待对方释放锁
多见于嵌套锁的情况:
线程中信息传递的模式
- 所有的线程共享一个被lock保护的队列
- 发送者向队列中加入数据或请求,接受者送队列中移出数据或请求
- 队列可以保存任意类型的对象,对象必须是不可变类型以防止共享内存
- 队列处理请求时,线程仍在继续执行