📑前言
本文主要是【JUC】——JUC-公平锁和非公平锁的文章,如果有什么需要改进的地方还请大佬指出⛺️
🎬作者简介:大家好,我是听风与他🥇
☁️博客首页:CSDN主页听风与他
🌄每日一句:狠狠沉淀,顶峰相见
1.公平锁
- 公平锁: 多个线程按照申请锁的顺序去获得锁,线程会直接进入队列去排队,永远都是队列的第一位才能得到锁。
2.非公平锁
- 非公平锁:多个线程去获取锁的时候,会直接尝试去获取,获取不到,再去进入等待队列,如果
我们可以来测试一下公平锁和非公平锁的表现情况:
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
这里我们选择使用第二个构造方法,可以选择是否为公平锁实现:
public static void main(String[] args) throws InterruptedException {
ReentrantLock lock = new ReentrantLock(true);
//参数,false为非公平锁,true为公平锁
Runnable action = () -> {
System.out.println("线程 "+Thread.currentThread().getName()+" 开始获取锁...");
lock.lock();
System.out.println("线程 "+Thread.currentThread().getName()+" 成功获取锁!");
lock.unlock();
};
for (int i = 0; i < 10; i++) { //建立10个线程
new Thread(action, "T"+i).start();
}
}
这里我们只需要对比将在1秒后开始获取锁...
和成功获取锁!
的顺序是否一致即可,如果是一致,那说明所有的线程都是按顺序排队获取的锁,如果不是,那说明肯定是有线程插队了。
打印公平锁结果:
线程 T3 开始获取锁...
线程 T5 开始获取锁...
线程 T0 开始获取锁...
线程 T7 开始获取锁...
线程 T2 成功获取锁!
线程 T6 开始获取锁...
线程 T4 开始获取锁...
线程 T9 开始获取锁...
线程 T6 成功获取锁!
线程 T5 成功获取锁!
线程 T4 成功获取锁!
线程 T8 成功获取锁!
线程 T9 成功获取锁!
线程 T0 成功获取锁!
线程 T7 成功获取锁!
线程 T3 成功获取锁!
线程 T1 成功获取锁!
我们发现,6,4,9三个线程是在其他线程已经成功获取锁之后才开始获取锁的,而成功获取锁的顺序也是6,4,9
打印非公平锁结果:
线程 T7 开始获取锁...
线程 T5 开始获取锁...
线程 T1 开始获取锁...
线程 T6 开始获取锁...
线程 T7 成功获取锁!
线程 T3 开始获取锁...
线程 T2 开始获取锁...
线程 T0 开始获取锁...
线程 T9 开始获取锁...
线程 T4 开始获取锁...
线程 T8 开始获取锁...
线程 T3 成功获取锁!
线程 T1 成功获取锁!
线程 T8 成功获取锁!
线程 T0 成功获取锁!
线程 T6 成功获取锁!
线程 T5 成功获取锁!
线程 T9 成功获取锁!
线程 T4 成功获取锁!
线程 T2 成功获取锁!
非公平锁明显没有顺序。
运行结果可以发现,在公平模式下,确实是按照顺序进行的,而在非公平模式下,一般会出现这种情况:线程刚开始获取锁马上就能抢到,并且此时之前早就开始的线程还在等待状态,很明显的插队行为。