死锁:两个线程互相等待对方释放锁才可以继续运行。
避免死锁的常见方法:
1.避免一个线程同时获取多个锁
2.避免一个线程在锁内同时占用多个资源,尽量保证一个锁只占用一个资源
3.尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制
4.对于数据库,加锁个解锁必须在一个数据库连接里,否则会出现解锁失败的情况
volatile变量:
1.可见性,对一个volatile变量的读,总是能看到(任意线程)对这个 volatile变量最后的写入
2.原子性,对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性
jdk1.5开始volatile变量的写-读可以实现线程之间的通信,从内存角度,volatile的写-读与锁的释放-获取具有相同的内存效果。
volatile写的内存语义如下:
当写一个volatile变量时,jvm会把该线程对应的本地内存中的共享变量值刷新到主内存
volatile读内存语义如下:
当读一个volatile变量时,jvm会把该线程对应的本地内存置为无效,线程接下来将从主内存中读取共享变量
volatile变量状态示意图如下(图片来源:Java并发变成的艺术)