线程状态Thread.state 枚举 watting不见不散 timed_watting过时不候
wait() 在哪里睡在哪里醒,醒了继续执行,存在被虚假唤醒可能,解决办法:必须放在循环里执行
导致这个原因的是wait从哪等待,就从哪唤醒,唤醒会继续往下执行。
如果是if,它不会进行二次判断;所以wait使用要在while内,while会一直判断是否符合条件。
copyonwriteArrayList 写时复制
blocking Queue 阻塞队列常用方法
不同线程访问同一个对象中synchronized 方法和静态synchronized方法时不会冲突,因为一个加的是对象锁一个是类锁
不同线程访问不同对象中静态synchronized 方法和静态synchronized方法时会冲突,因为引用的对象是相同的
interrupt 和isInterrupted可配合优雅停止线程,但不会立即停止,线程执行完isInterrupted标志位复原,重点sleep join等操作导致线程阻塞时标志位清除,需try catch重新设置标志位
isInterrupted和interrupted区别,都会获取标志位状态是否停止线程,后者会清除标志位状态
SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果定义为 static,必须 加锁,或者使用 DateUtils 工具类。或ThreadLocal<DateFormart>
必须回收自定义的 ThreadLocal 变量
高并发时,同步调用应该去考量锁的性能损耗。能用无锁数据结构,就不要用锁;能锁区块,就 不要锁整个方法体;能用对象锁,就不要用类锁。
.【强制】对多个资源、数据库表、对象同时加锁时,需要保持一致的加锁顺序,否则可能会造成死锁。 说明:线程一需要对表 A、B、C 依次全部加锁后才可以进行更新操作,那么线程二的加锁顺序也必须是 A、B、C,否则可 能出现死锁。
【强制】并发修改同一记录时,避免更新丢失,需要加锁。要么在应用层加锁,要么在缓存加锁,要么 在数据库层使用乐观锁,使用 version 作为更新依据。
正例:
Lock lock = new XxxLock();
// ...
lock.lock();
try {
doSomething();
doOthers();
} finally {
lock.unlock();
}
反例:
Lock lock = new XxxLock();
Java 开发手册(黄山版)
16/51
// ...
try {
// 如果此处抛出异常,则直接执行 finally 代码块
doSomething();
// 无论加锁是否成功,finally 代码块都会执行
lock.lock();
doOthers();
} finally {
lock.unlock();
}
锁优化
并发容器