一、线程带来的风险
- 安全性问题
- 活跃性问题
- 性能问题
- 线程安全性可能是非常复杂的,在没有充足同步的情况下,多个线程中的操作执行顺序是不可预测的,甚至会产生奇怪的结果。
- 死锁:当一个线程永远保持有一个锁,并且其他线程都尝试获得这个锁时,那么他们将永远被阻塞。在线程A持有锁L并想获得锁M的同时,线程B持有锁M并尝试获得锁L,那么这两个线程将永远地等待下去,这种情况就是最简单的死锁形式。
- 饥饿:当线程由于无法访问它所需要的资源而不能继续执行时,就发生了“饥饿”,引发饥饿的最常见资源就是CPU时钟周期。如果在java应用程序中对线程的优先级使用不当,或者在持有锁时执行一些无法结束的结构(例如无限循环,或者无限制的等待某个资源),那么也可能导致饥饿,因为其他需要这个锁的线程将无法得到它。
- 活锁:当多个相互协作的线程对彼此进行响应从而修改各自的状态, 并使得任何一个线程都无法继续执行时,就发生了活锁。这就像两个过于礼貌的人在半路上面对面相遇,他们彼此都让出对象的路,然而又在另一条路上相遇了,因此他们就这样反复地避让下去。
- 性能问题包括多个方面,例如服务时间过长,响应不灵敏,吞吐率过低,资源消耗过高,或者可伸缩性较低等。
- 在多线程程序中,当线程调度器临时挂起活跃线程并转而运行另一个线程时,就回频繁地出现上下文切换操作,这种操作将带来极大的开销:保存和恢复执行上下文,丢失局部数据,并且CPU时间将更多地花在线程调度而不是线程运行上。
参考: