简介
本文介绍Java多线程的基础知识。包括:多线程同步的实现方式,死锁产生的条件,如何避免死锁。
多线程同步的方案
方式 | 优点 | 缺点 | 使用场景 |
synchronized | 使用简单;CPU占用低 | 响应缓慢(并发性能差);不灵活。 | 并发量低;大的代码块 同步方法/代码块 |
并发集合(List, Map) 例:ConcurrentHashMap等 | 并发性能高 | ||
java.util.concurrent.locks.* (锁) | 并发性能高;灵活 | CPU占用高(CAS通病);需手动加锁、释放锁 | 例如:可重入锁(ReentrantLock) |
java.util.concurrent.atomic.* (原子变量) | 并发性能高(比locks还高) | 只能锁一个变量 | 可升级为原子变量队列 |
ThreadLocal | |||
wait(),notify() (等待与唤醒) | |||
java.util.concurrent.BlockingQueue (阻塞队列) |
死锁
死锁产生的条件
- 互斥条件
- 指线程对己经获取到的资源进行排它性使用,即该资源同时只由一个线程占用。如果此时还有其他线程请求获取该资源,则请求者只能等待,直至占有资源的线程释放该资源。
- 请求并持有条件
- 指一个线程己经持有了至少一个资源,但又提出了新的资源请求,而新资源己被其他线程占有,所以当前线程会被阻塞,但阻塞的同时并不释放自己己经获取的资源。
- 不可剥夺条件
- 指线程获取到的资源在自己使用完之前不能被其他线程抢占,只有在自己使用完毕后才由自己释放该资源。
- 环路等待条件
- 指在发生死锁时,必然存在一个线程一资源的环形链,即线程集合{T0, Tl, T2,…,Tn}中的T0正在等待一个T1占用的资源,T1正在等待T2占用的资源,……Tn正在等待己被T0占用的资源。
如何避免死锁
要避免死锁,只需要破坏掉至少一个构造死锁的必要条件即可,但是学过操作系统的读者应该都知道, 目前只有请求并持有和环路等待条件是可以被破坏的
请先
!