李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
Java锁--公平和非公平锁
Leefs
2020-02-26 AM
1421℃
0条
# Java锁--公平和非公平锁 ### 前言 公平锁和非公平锁的理解:**如果一个线程组里,如果能保证每个线程都拿到锁,这个锁就是公平锁。相反,如果保证不了每个线程都能拿到锁,也就是存在线程饿死,那么这个锁就是非公平锁。** ### 一、概念 公平锁:是指多个线程按照申请锁的顺序来获取锁,通过队列FIFO,先进先出,类似排队打饭,先来后到。 非公平锁:是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。在高并发的情况下,有可能会造成优先级反转或者饥饿现象。 ### 二、实现原理 并发包中通过ReentrantLock的创建可以指定构造函数的boolean类型来得到公平锁和非公平锁,默认是非公平锁 **两者的区别:** 公平锁:就是很公平,在并发环境中,每个线程在获取锁时会查看此锁维护的等待队列,如果为空,或者当前线程是等待队列的第一个,就占有锁,否则就会加入到等待队列中,以后会按照FIFO的规则从队列中取到自己 非公平锁:比较粗鲁,上来就直接尝试占有锁,入股尝试失败,就再采用类似公平锁那种方式。 ### 三、代码示例 `ReentrantLock()`为true代表公平锁,为false代表非公平锁 **公平锁代码示例** ```java public class MyFairLock { private ReentrantLock lock = new ReentrantLock(true); public void testFail(){ try{ lock.lock(); System.out.println(Thread.currentThread().getName()+"线程获取到了锁"); } finally { lock.unlock(); } } public static void main(String[] args) { MyFairLock fairLock = new MyFairLock(); Runnable runnable = () -> { System.out.println(Thread.currentThread().getName()+"线程启动"); fairLock.testFail(); }; Thread[] threadArray = new Thread[10]; for(int i=0;i<10;i++){ threadArray[i] = new Thread(runnable); } for(int i=0;i<10;i++){ threadArray[i].start(); } } } ``` 可以看到,获取锁的线程顺序正是线程启动的顺序。 **运行结果** ```java Thread-0线程启动 Thread-0线程获取到了锁 Thread-1线程启动 Thread-1线程获取到了锁 Thread-2线程启动 Thread-2线程获取到了锁 Thread-3线程启动 Thread-3线程获取到了锁 Thread-4线程启动 Thread-4线程获取到了锁 Thread-6线程启动 Thread-6线程获取到了锁 Thread-8线程启动 Thread-8线程获取到了锁 Thread-5线程启动 Thread-5线程获取到了锁 Thread-7线程启动 Thread-7线程获取到了锁 Thread-9线程启动 Thread-9线程获取到了锁 ``` 可以看出非公平锁对锁的获取是乱序的,即有一个抢占锁的过程。 **非公平锁代码示例** ```java public class MyNonfairLock { private ReentrantLock lock = new ReentrantLock(false); public void testFail(){ try{ lock.lock(); System.out.println(Thread.currentThread().getName()+"线程获取到了锁"); } finally { lock.unlock(); } } public static void main(String[] args) { MyNonfairLock nonfairLock = new MyNonfairLock(); Runnable runnable = () -> { System.out.println(Thread.currentThread().getName()+"线程启动"); nonfairLock.testFail(); }; Thread[] threadArray = new Thread[10]; for(int i=0;i<10;i++){ threadArray[i] = new Thread(runnable); } for(int i=0;i<10;i++){ threadArray[i].start(); } } } ``` **运行结果** ```java Thread-0线程启动 Thread-2线程启动 Thread-1线程启动 Thread-2线程获取到了锁 Thread-3线程启动 Thread-3线程获取到了锁 Thread-4线程启动 Thread-4线程获取到了锁 Thread-5线程启动 Thread-1线程获取到了锁 Thread-6线程启动 Thread-6线程获取到了锁 Thread-0线程获取到了锁 Thread-5线程获取到了锁 Thread-8线程启动 Thread-8线程获取到了锁 Thread-9线程启动 Thread-9线程获取到了锁 Thread-7线程启动 Thread-7线程获取到了锁 ``` ### 四、优点和缺点 非公平锁性能高于公平锁性能。首先,在恢复一个被挂起的线程与该线程真正运行之间存在着严重的延迟。而且,非公平锁能更充分的利用cpu的时间片,尽量的减少cpu空闲的状态时间。 *参考文章链接:https://www.jianshu.com/p/eaea337c5e5b*
标签:
并发编程
,
锁
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://lilinchao.com/archives/644.html
上一篇
Java锁--可重入锁和递归锁简介
下一篇
countDownLatch简介
取消回复
评论啦~
提交评论
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
标签云
Netty
Livy
哈希表
SpringBoot
前端
Java
链表
Thymeleaf
SQL练习题
查找
Java阻塞队列
字符串
排序
ClickHouse
MySQL
递归
工具
栈
Stream流
JavaWEB项目搭建
锁
微服务
Java编程思想
持有对象
人工智能
散列
Map
SpringCloudAlibaba
Elastisearch
DataWarehouse
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞