《Java高并发编程详解-多线程架构与设计》线程安全与数据同步

摘自《Java高并发编程详解-多线程架构与设计》第四章

定义

共享资源:多个线程对同一资源访问(读写)
线程安全:多个线程对同一资源访问的数据是一致的。

Synchronized使用

同步方法

同步代码块

深入 synchronized关键字

p66-67
不应该叫synchronized(mutex)为锁,而应该是某个线程获取了与mutex关联的monitor锁。

当使用synchronize锁住某段代码, 几个线程一起去访问时。使用jstack查看堆栈时可以发现,只有一个线程持有锁locked,其他线程处于由于AccessResource被阻塞处于BLOCKED状态。

使用jvm命令 javap对文中的Mutex Class反编译可以发现 monitor enter 与 monitor exit
成对出现。

在这里插入图片描述

使用synchronized注意的问题

  1. 与monitor关联的对象不能为null

  2. synchronized的作用域不要太大

  3. 不同的monitor交叉使用时,保证顺序一致,否则容易死锁
    ps:可以使用jstack pid 查看死锁

     methodA(){ 
     		synchronized(A)
     			synchronized(B)
     			}
     methodB(){
     		synchronized(B)
     			synchronized(A)
     			}
    

    解决方法:保证顺序一致即可。

4.容易死锁的原因

  1. 交叉锁的使用

  2. 内存不足
    当线程1,2都需要30M的内存,但是线程1申请了10M了,线程2申请了20M,彼此都在等待对方的资源释放。

  3. 一问一答的数据交换
    服务端等待客户端的请求,但是某种原因导致错过了。结果服务端就一直等待。 ps:客户端也是。
    4 .数据库锁

  4. 文件锁
    某个线程获取了文件锁意外退出,其他读取该文件的线程会死锁直到系统释放该文件的句柄。

  5. 死循环
    使用就stack不会出现死锁的情况,但是CPU会飙升。

死锁检测

  1. 交叉锁引起的死锁可以通过jstack pid查看

  2. 死循环引起的死锁(假死)
    可以用jstack jconsole、jvisualvm查看 某个线程长时间处于runnable的状态

发布于2019年7月7日 16:40:31

posted @ 2019-07-07 16:15  thewindkee  阅读(118)  评论(0编辑  收藏  举报