锁
公平锁与非公平锁
公平锁是指在多线程并发访问共享资源的时候,会按照申请锁的顺序来获取锁。一般底层会使用一个队列,利用队列的FIFO特性来维护公平性,这样会杜绝并发时的的“饥饿”问题。
非公平锁是指多线程访问共享资源的时候,并不按照申请锁的顺序来获取锁,即后来的先获取,这样会造成优先级反转和饥饿现象。
在Java中的Synchronized就是典型的非公平锁。
通过ReentrantLock的构造方法可以指定该lock是一个公平锁。
可重入锁
可重入锁是指一个线程获取在到一个锁之后,在该锁尚未释放之前,再次遇到该锁,还可以再次获取。
Java中的Synchronized,及Lock体系都是可重入锁,如果锁不能重入就会造成死锁。对于显示的lock锁,几次加锁,就需要即此锁的释放。
独占锁和共享锁
独占锁是指该锁同一时间只能被一个线程锁占有。
共享锁:同一时间可以被多个线程锁占有。
Java中的Synchronized,ReentrantLock都是独占锁。
ReadWriteLock和Semphere都是共享锁。
乐观锁和悲观锁
悲观锁认为任何时候都共享资源的访问都会发生并发修改,因此必须加锁,不加锁则认为不安全。悲观锁适用于读多写少的情况。
乐观锁:对于共享资源的并发访问,不会发生修改。一般采用版本号机制和CAS算法实现。适用于读多于写的情况。
分段锁
分段锁是JDK7中ConcurrentHashMap的结构,在进行并发访问的时候,不是对整个桶数组加锁,而是分段加锁,只要不在同一段中就可以并行访问。
本质是细化锁的粒度,提高吞吐量。
自旋锁
自旋锁就是在获取锁的时候失败了,但不会立即阻塞,而是采用循环的方式不断尝试获取。
优点:减少线程上下文的切换。
缺点:浪费CPU资源。