线程带来的风险
安全性:多线程操作执行顺序的不可预测性 -- 永远不发生糟糕的事情;
活跃性:代码无法得到执行,死锁、饥饿问题 -- 某件正确的事情最终会发生;
性能问题:活跃性只意味着某件事最终会发生,但不是尽快发生;
- 线程安全性
当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称为这个类是线程安全的。
线程安全类中封装了必要的同步机制,所以客户端无需进一步采取同步措施。
- 原子性
竞态条件:基于一种可能失效的观察结果来做出判断或执行某个计算;
要保持状态的一致性,就需要在单个原子操作中更新所有的相关状态变量;
- 加锁机制
内置锁
java提供了一种内置的锁机制来支持原子性:同步代码块(Synchronized Block)
1 // java提供了一种内置的锁机制来支持原子性:同步代码块(Synchronized Block) 2 // 同步代码块包含两部分 3 // 一个作为锁的对象引用,一个作为由这个锁保护的代码块 4 synchronized (lock) { 5 // 访问或修改由锁保护的共享状态 6 }
重入:某线程试图获得一个已经由它自己持有的锁,这个请求会成功。重入的实现方式为,为每一个锁关联一个获取计数值和一个所有者线程,当计数值为0,这个锁认为没有任何线程持有。
重入避免了死锁情况的发生
// 如果内置锁不可重入,下面代码将发生死锁 public class Parent { public synchronized void doSomething() { } } public class Children extends Parent { public synchronized void doSomething() { super.doSomething(); } }
- 可见性