juc显示锁
java内置锁功能相对单一,不具备一些高级特性,比如:限时抢锁,中端抢锁.并且还好膨胀为操作系统的锁.
因此后续新增了Lock接口来提供这些功能.
ReentrantLock
可重入独占锁.默认是非公平锁,可以通过构造参数设置为公平锁.
synchronized默认是非公平锁,当owner thread空闲时,entrylist候选者线程在成为owner thread的时,也需要再次竞争来获取到锁.通常这样是为了提高系统执行速度.
使用
package com.lenovo.javautils.lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockTest {
public static int a = 1;
public static void main(String[] args) {
ReentrantLock reentrantLock = new ReentrantLock();
reentrantLock.lock();
try {
a++;
} catch (Exception e) {
e.printStackTrace();
} finally {
reentrantLock.unlock();
}
System.out.println(a);
}
}
LockSupport

和thread.sleep()区别:
1.sleep无法手动停止,localSupport可以通过unpart()停止.
2.sleep需要捕获异常,localSupport不需要.
3.thread.interrupt()方法,会让sleep抛出interruptException异常,但是只会让localSupport设置了中断标志.
和object.wait()区别:
1.Object.wait()方法需要在synchronized块中执行,而LockSupport.park()可以在任意地方执行.
2.object.notify必须在object.wait之后调用,不然会抛出异常.localSupport的park和unpark没有此限制.
分类
1.可重入锁和不可重入锁
可重入指的是一个线程可以多次获取一把锁.ReentrantLock类是可重入锁的一个标准实现类.
2.悲观锁和乐观锁
Java的synchronized重量级锁是一种悲观锁.
Java中的乐观锁基本都是通过CAS自旋操作实现的.synchronized轻量级锁和ReentrantLock都是乐观锁.
3.公平锁和非公平锁
使用公平锁,比如线程A、B、C、D依次去获取锁,假如此时持有锁的是线程A,然后线程B、C、D尝试获取锁,就会进入一个等待队列。当线程A释放掉锁之后,会唤醒下一个线程B去获取锁。在唤醒线程B的这个过程中,如果有别的线程E尝试去请求锁,那么线程E是可以先获取到的,这就是插队。为什么线程E可以插队呢?因为CPU唤醒线程B需要进行线程的上下文切换,这个操作需要一定的时间,线程E可能与线程A、B不在同一个CPU内核上执行,而是在其他的内核上执行,所以不需要进行线程的上下文切换。在线程A释放锁和线程B被唤醒的这段时间,锁是空闲的,其他内核上的线程E此时就能趁机获取非公平锁,这样做的目的主要是利用锁的空档期,提高其利用效率。
4.可中断锁和不可中断锁
在获取锁的时候,等待一段时间,获取不到就不再进行等待,为可中断锁.
Java的synchronized内置锁就是一个不可中断锁,而JUC的显式锁(如ReentrantLock)是一个可中断锁。
5.共享锁和独占锁
每次只能有一个线程持有的锁,为独占锁.ReentrantLock为独占锁.读写锁中读锁,countDownLatch是共享锁,写锁是独占锁.
Last updated
Was this helpful?