《Java高并发编程详解-多线程架构与设计》线程安全与数据同步
定义
共享资源:多个线程对同一资源访问(读写)
线程安全:多个线程对同一资源访问的数据是一致的。
Synchronized使用
同步方法
同步代码块
深入 synchronized关键字
p66-67
不应该叫synchronized(mutex)为锁,而应该是某个线程获取了与mutex关联的monitor锁。
当使用synchronize锁住某段代码, 几个线程一起去访问时。使用jstack查看堆栈时可以发现,只有一个线程持有锁locked,其他线程处于由于AccessResource被阻塞处于BLOCKED状态。
使用jvm命令 javap对文中的Mutex Class反编译可以发现 monitor enter 与 monitor exit
成对出现。
使用synchronized注意的问题
-
与monitor关联的对象不能为null
-
synchronized的作用域不要太大
-
不同的monitor交叉使用时,保证顺序一致,否则容易死锁
ps:可以使用jstack pid 查看死锁
如methodA(){ synchronized(A) synchronized(B) } methodB(){ synchronized(B) synchronized(A) }
解决方法:保证顺序一致即可。
4.容易死锁的原因
-
交叉锁的使用
-
内存不足
当线程1,2都需要30M的内存,但是线程1申请了10M了,线程2申请了20M,彼此都在等待对方的资源释放。 -
一问一答的数据交换
服务端等待客户端的请求,但是某种原因导致错过了。结果服务端就一直等待。 ps:客户端也是。
4 .数据库锁 -
文件锁
某个线程获取了文件锁意外退出,其他读取该文件的线程会死锁直到系统释放该文件的句柄。 -
死循环
使用就stack不会出现死锁的情况,但是CPU会飙升。
死锁检测
-
交叉锁引起的死锁可以通过jstack pid查看
-
死循环引起的死锁(假死)
可以用jstack jconsole、jvisualvm查看 某个线程长时间处于runnable的状态
发布于2019年7月7日 16:40:31