java多线程-锁分析

回忆了一下多线程锁相关内容,记录下来自己的理解,免得时间长遗忘。都是个人体会,不加实现代码,读者不必纠结,有错误请指出。

1.死锁

当在同步代码块里再调用同步代码时,当里层和外层不是同一把锁,可能会产生死锁问题。比如用ReentrantLock 实现同步时,两个不同的lock对象,线程竞争时就有可能死锁。线程1获取到锁1,需要获取锁2才能执行内部代码,但是内部代码锁2,被线程2持有,线程2又在等待线程1的锁,这样互相等待就成了死锁。

2.可重入锁

synchronized 和 ReentrantLock 都是可重入锁。个人理解为如果加锁的方法或者代码块里边调用了加锁的方法和代码块,线程只要获取最外层的锁,在执行里层加锁的代码时,就不用再次竞争获取锁,即为可重入。本质是内层和里层的同步用的是同一把锁,所以不会导致死锁问题出现,里层也不用再获取锁。需要注意,内层外层需要是同一个锁对象,才能可重入。

3.读写锁

多个线程对同一个共享对象进行操作,就会产生线程安全问题,所以要加锁,保证同一时间,只有一个线程可以对共享对象进行操作。操作简单的可以分为读和写,读写锁就是把这个操作细分出来的锁,一个是“读锁“,另一个是“写锁“,ReentrantReadWriteLock 是读写锁。当用读锁时,获取到锁的线程可以进行读操作,其余的线程可以写操作;当写锁时,获取到锁的线程可以进行写操作,其余的线程可以读操作。

4.公平锁和非公平锁

公平锁会维护一个等待队列,多个在阻塞状态等待的线程会被插入到这个等待队列。在调度时是按它们所发请求的时间顺序获取锁,而对于非公平锁,当一个线程请求非公平锁时,如果此时该锁变成可用状态,那么这个线程会跳过等待队列中所有的等待线程而获得锁。如果请求锁的平均时间间隔较长,建议使用公平锁,反之建议使用非公平锁。

我们在创建可重入锁时,也可以通过调用带布尔类型参数的构造函数来指定该锁是否是公平锁。ReentrantLock(boolean fair)。

posted @ 2020-07-21 16:30  自习小夫子  阅读(37)  评论(0编辑  收藏