李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
Java锁--公平和非公平锁
Leefs
2020-02-26 AM
1983℃
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
NLP
4
标签云
数据结构
SpringBoot
排序
Python
MyBatis
散列
Jenkins
算法
Java
gorm
Redis
并发编程
Elastisearch
国产数据库改造
序列化和反序列化
数学
正则表达式
ClickHouse
Kafka
Thymeleaf
Ubuntu
Tomcat
Linux
FastDFS
二叉树
BurpSuite
HDFS
Java工具类
Spark RDD
微服务
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭