Java并发编程锁之独占公平锁与非公平锁比较
Java并发编程锁之独占公平锁与非公平锁比较
公平锁和非公平锁理解:
在上一篇文章中,我们知道了非公平锁。其实Java中还存在着公平锁呢。公平二字怎么理解呢?和我们现实理解是一样的。大家去排队本着先来先得到的原则,在排队中,无论身份贵贱,一律平等对待。这是就是我们现实生活中的公平。大家都喜欢公平的。但是在Java中默认是非公平的,为什么呢?
本文主要内容:公平锁的现实生活理解;公平锁演示;为什么Java中默认是非公平锁(公平锁的非公平锁的比较)
本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《Lock系列》教程的第四篇:《Java并发包下锁学习第五篇:公平锁理解及与非公平锁的比较》。
生活中的例子:
同样还是去ATM机取钱的例子。假设现在有3个人使用ATM取钱。路人甲不会用ATM,自己摸索耗时5min,然后终于学会怎么使用了,但是密码又忘掉了。打电话给家里人咨询耗时1min.当路人甲操作完成之后,后面两个人排队接着依次操作,这种方式是谁先到谁先操作,操作完成之后下一个人才可以操作的,不管贫富贵贱,不管你是取100还是取1W,取1W的人在取100的人后面,就要排着队等着,这种看上去很公平的,无论贵贱,大家依次操作,这种操作模式站在多线程并发角度来看的话,就是公平锁操作。
在路人甲总耗时6min之后,路人乙和路人丁两个人操作耗时3min。也就是三个人总耗时9min.为什么会产生这种情况呢?因为路人甲堵着了。一直占着锁的资源。在路人甲操作的过程中,其他人只能排队等待。如果路人甲不会操作,排在他后面的路人丙插队询问路人甲,自己可以先插队操作ATM,同时教会路人甲。如果甲同意,则丙可以操作完成后,甲可以学着别人操作,有可能路人甲2min也能操作完成。这个时候,三个人总耗时就是5min了;如果甲不同意丙插队操作,那么丙只能回到原来位置上,进行排队等待。这种操作模式站在多线程并发角度来考虑的话,路人甲在模式及和家人通话耗时看着是CPU切换上下文的耗时。路人丙插队后获取ATM资源,这个操作可以看着是非公平的,因为丙的进入时间比路人乙晚,但是丙先操作了。但是从最后三人总耗时来看,路人丙插队,是的效率提高了。这种操作在Java并发中,称之为非公平锁。
需要说明的是,无论是显式锁还是隐式锁默认都是非公平的。因为非公平能够提升系统的吞吐量。
非公平锁的定义:
线程先尝试着获取同步状态操作(丙先尝试着插队),如果获取到,就对共享变量操作(甲同意丙的插队,丙就操作ATM机),如果获取不到,就接着排队。
使用方法二:独占公平演示
需求:控制台打印的结果和线程顺序一致。代码如下:
此时代码和上一次代码唯一区别如上图:在实例化lock的是有个参数,设置了true.
运行结果:
从运行结果中,我们发现控制台打印出的获取锁的顺序和调用锁的时候顺序是一样的, 已经达到我们预期结果了。但是,还是每次只有一个线程操作,等这个线程操作完成释放锁后,其他线程才可以接着获取锁。
公平锁与非公平锁的比较
问题:
为什么并发大师Doug Lea把ReentrantLock设计默认模式是非公平的?
其实要回答这个问题,就需要从公平锁与非公平锁的不同来进行比较了。我们先来看看ATM机操作在公平锁和非公平锁的场景下,如下图:
公平锁:大家都排队,如果一个线程堵着了(路人甲),其他线程只能等待这个。最终,三个线程操作完成,总耗时9min.
非公平锁情况下:多个线程操作的共享资源的时候,发现共享资源还没有被锁定(路人甲还在摸索过程),就尝试插队(路人丙尝试和甲沟通,先插队操作并教会甲),如果插队成功(甲同意了),就操作共享资源(丙先操作ATM机);如果插队失败(甲不同意),接着排队(丙回到队伍中排队)。如果插队成功,最终耗时:5min.
从中我们可以看出公平锁和非公平锁的优缺点了。
优缺点比较:
非公平锁:
优点:效率高;缺点:容易导致线程“饥饿”。当多个线程使用非公平的话,有可能有一个线程一直就获取不到竞争权,导致这个线程会“饥饿而死”。
适用场景:
如果在不考虑TPS(单位时间内成功完成的次数)作为唯一考量指标的场景下,可以使用非公平锁来操作,因为非公平锁能提高系统的吞吐量;
公平锁:
优点:避免了线程的“饥饿”;缺点:性能相对于公平锁会差很多。
欢迎来聊
Java并发编程锁之独占公平锁与非公平锁比较的更多相关文章
- Java并发编程:用AQS写一把可重入锁
Java并发编程:自己动手写一把可重入锁详述了如何用synchronized同步的方式来实现一把可重入锁,今天我们来效仿ReentrantLock类用AQS来改写一下这把锁.要想使用AQS为我们服务, ...
- 【Java并发编程实战】-----“J.U.C”:CLH队列锁
在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...
- Java并发编程:自己动手写一把可重入锁
关于线程安全的例子,我前面的文章Java并发编程:线程安全和ThreadLocal里面提到了,简而言之就是多个线程在同时访问或修改公共资源的时候,由于不同线程抢占公共资源而导致的结果不确定性,就是在并 ...
- 【Java并发编程实战】-----“J.U.C”:CLH队列锁
在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格依照FIFO的队列.他可以确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...
- java并发编程的艺术——第五章总结(Lock锁与队列同步器)
Lock锁 锁是用来控制多个线程访问共享资源的方式. 一般来说一个锁可以防止多个线程同时访问共享资源(但有些锁可以允许多个线程访问共享资源,如读写锁). 在Lock接口出现前,java使用synchr ...
- 【漫画】JAVA并发编程 J.U.C Lock包之ReentrantLock互斥锁
在如何解决原子性问题的最后,我们卖了个关子,互斥锁不仅仅只有synchronized关键字,还可以用什么来实现呢? J.U.C包中还提供了一个叫做Locks的包,我好歹英语过了四级,听名字我就能马上大 ...
- 转:【Java并发编程】之一:可重入内置锁
每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁.线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁.获得内置锁的唯一途径就是进入由这个锁保护的同步代码块 ...
- 【Java并发编程】之一:可重入内置锁
每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁.线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁.获得内置锁的唯一途径就是进入由这个锁保护的同步代码块 ...
- java并发编程(一)可重入内置锁
每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁.线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁.获得内置锁的唯一途径就是进入由这个锁保护的同步代码块 ...
- java并发编程(8)原子变量和非阻塞的同步机制
原子变量和非阻塞的同步机制 一.锁的劣势 1.在多线程下:锁的挂起和恢复等过程存在着很大的开销(及时现代的jvm会判断何时使用挂起,何时自旋等待) 2.volatile:轻量级别的同步机制,但是不能用 ...
随机推荐
- git问题待更新
git pull failed 错误解决 情况: 刚开始的项目,需要创建一个项目,然后pull从远端的项目,创建分支dev,然后从dev分支开始拉取远端的代码 出现错误,说git pull faile ...
- Python学习笔记--装饰器的实验
装饰器既然可以增加原来函数的功能,那能不能改变传给原函数的参数呢? 我们实验一下,先上代码: #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date ...
- Docker 安装 Nginx 负载均衡配置
Docker 安装 # 1)安装依赖包 yum install -y yum-utils device-mapper-persistent-data lvm2 # 2)添加Docker软件包源(否则d ...
- 读书笔记-《Mysql技术内幕》
MYSQL 技术内幕 Mysql体系 连接池组件 管理服务和工具 SQL接口 查询分析器 优化器 缓冲 插件式存储引擎 物理文件 存储引擎 InnoDB(默认引擎) 支持事务 行锁设计 多版本并发控制 ...
- tomcat服务器的应用总结
tomcat的安装和部署: >> Web的基本入门: |-- C/S架构:客户端和服务器: |-- B/S架构:浏览器和服务器: >> 服务器当中可以放入的资源: |-- 静态 ...
- OpenCV图像增强(python)
为了得到更加清晰的图像我们需要通过技术对图像进行处理,比如使用对比度增强的方法来处理图像,对比度增强就是对图像输出的灰度级放大到指定的程度,获得图像质量的提升.本文主要通过代码的方式,通过OpenCV ...
- Core + Vue 后台管理基础框架3——后端授权
1.前言 但凡业务系统,授权是绕不开的一环.见过太多只在前端做菜单及按钮显隐控制,但后端裸奔的,觉着前端看不到,系统就安全,掩耳盗铃也好,自欺欺人也罢,这里不做评论.在.NET CORE中,也见过不少 ...
- TCP/IP协议基本知识
1.TCP/IP协议中主机与主机之间通信的三要素: IP地址(IP address) 子网掩码(subnet mask) IP路由(IP router) 2.IP地址的分类及每一类的范围: A类1-1 ...
- 精通HTML DOM
DOM 1. 属性方法 类型/返回类型 说明 nodeName String 节点名称,根据节点的类型而定义 nodeValue string 节点的值,同样根据节点的类型而定义 nodeType s ...
- Hadoop集群搭建(五)~搭建集群
继上篇关闭防火墙之后,因为后面我们会管理一个集群,在VMware中不断切换不同节点,为了管理方便我选择xshell这个连接工具,大家也可以选择SecureCRT等工具. 本篇记录一下3台机器集群的搭建 ...