mysql的锁是公平的么_lock 默认公平锁还是非公平锁?公平锁是如何定义?如何实现...
ReentrantLock的实现是基于其内部类FairSync(公平锁)和NonFairSync(非公平锁)实现的。 其可重入性是基于Thread.currentThread()实现的: 如果当前线程已经获得了执行序列中的锁, 那执行序列之后的所有方法都可以获得这个锁。
公平锁:
公平和非公平锁的队列都基于锁内部维护的一个双向链表,表结点Node的值就是每一个请求当前锁的线程。公平锁则在于每次都是依次从队首取值。
锁的实现方式是基于如下几点:
表结点Node和状态state的volatile关键字。
sum.misc.Unsafe.compareAndSet的原子操作(见附录)。
非公平锁:
在等待锁的过程中, 如果有任意新的线程妄图获取锁,都是有很大的几率直接获取到锁的。
ReentrantLock锁都不会使得线程中断,除非开发者自己设置了中断位。
ReentrantLock获取锁里面有看似自旋的代码,但是它不是自旋锁。
ReentrantLock公平与非公平锁都是属于排它锁。
公平锁和非公平锁在说的获取上都使用到了 volatile 关键字修饰的state字段, 这是保证多线程环境下锁的获取与否的核心。
但是当并发情况下多个线程都读取到 state == 0时,则必须用到CAS技术,一门CPU的原子锁技术,可通过CPU对共享变量加锁的形式,实现数据变更的原子操作。
volatile 和 CAS的结合是并发抢占的关键。
公平锁的实现机理在于每次有线程来抢占锁的时候,都会检查一遍有没有等待队列,如果有, 当前线程会执行如下步骤:
/**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
其中hasQueuedPredecessors是用于检查是否有等待队列的。
非公平锁在实现的时候多次强调随机抢占:
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
当当前拥有锁的线程释放锁之后, 且非公平锁无线程抢占,就开始线程唤醒的流程。
通过tryRelease释放锁成功,调用LockSupport.unpark(s.thread); 终止线程阻塞
private void unparkSuccessor(Node node) {
// 强行回写将被唤醒线程的状态
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
Node s = node.next;
// s为h的下一个Node, 一般情况下都是非Null的
if (s == null || s.waitStatus > 0) {
s = null;
// 否则按照FIFO原则寻找最先入队列的并且没有被Cancel的Node
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
// 再唤醒它
if (s != null)
LockSupport.unpark(s.thread);
}
非公平锁性能高于公平锁性能的原因:
在恢复一个被挂起的线程与该线程真正运行之间存在着严重的延迟。
假设线程A持有一个锁,并且线程B请求这个锁。由于锁被A持有,因此B将被挂起。当A释放锁时,B将被唤醒,因此B会再次尝试获取这个锁。与此同时,如果线程C也请求这个锁,那么C很可能会在B被完全唤醒之前获得、使用以及释放这个锁。这样就是一种双赢的局面:B获得锁的时刻并没有推迟,C更早的获得了锁,并且吞吐量也提高了。
当持有锁的时间相对较长或者请求锁的平均时间间隔较长,应该使用公平锁。在这些情况下,插队带来的吞吐量提升(当锁处于可用状态时,线程却还处于被唤醒的过程中)可能不会出现。
mysql的锁是公平的么_lock 默认公平锁还是非公平锁?公平锁是如何定义?如何实现...相关推荐
- 【代码】ReentrantLock还可以指定为公平锁
ReentrantLock还可以指定为公平锁 默认非公平 参数为true表示为公平锁,请对比输出结果 import java.util.concurrent.locks.ReentrantLock;/ ...
- mysql触发器行锁_MySQL 之 视图、触发器、存储过程、函数、事物与数据库锁
需求: 有一个账户,两个人在同一时间要对此账户操作,A要对账户充值100块,B要从账户中取出100块.操作前都要先看一下账户的 余额然后再操作. --窗口1 用户进行充值 --充值前 先查看余额 se ...
- 存储过程没有执行完后没有释放锁_【大厂面试07期】说一说你对synchronized锁的理解?...
PS:本文已收录到1.3 K+ Star 数的开源项目-<大厂面试指北>,如果想要了解更多,可以看一看,项目地址如下: https://github.com/NotFound9/inter ...
- java中怎么判断一段代码时线程安全还是非线程安全_24张图带你彻底理解Java中的21种锁...
(给ImportNew加星标,提高Java技能) 转自:悟空聊架 本篇主要内容如下: 本篇文章已收纳到我的 Java 在线文档. Github.我的 SpringCloud 实战项目持续更新中. 帮你 ...
- 还不会使用分布式锁?教你三种分布式锁实现的方式
摘要:在单进程的系统中,当存在多个线程可以同时改变某个变量时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量,而同步本质上通过锁来实现. 本文分享自华为云社区<还不 ...
- 还记得那场关于“分布式锁”的经典论战吗?
锁的目的在于对于共享资源访问的一个互斥控制,单机场景下我们可以基于jvm的锁进行实现就ok了,分布式场景下的实现方案有很多,有人可能会想到基于redis实现. 有关Redis分布式锁的文章可谓多如牛毛 ...
- java 7 锁优化_自Java 6/Java 7开始,Java虚拟机对内部锁的实现进行了一些优化。这些优化主要包括锁消除(Lock Elision)、锁粗化(Lock Coarse...
自Java 6/Java 7开始,Java虚拟机对内部锁的实现进行了一些优化.这些优化主要包括锁消除(Lock Elision).锁粗化(Lock Coarsening).偏向锁(Biased Loc ...
- 华为手机锁屏下拉怎么设置_华为手机怎么设置会滚动的锁屏文字?设置步骤超简单,一看就会...
小米手机设置锁屏滚动文字是通过自定义运营商名称来实现的,但是华为手机并不能自定义运营商名称,大部分华为手机只能选择显示或不显示运营商名称.那么问题来了,华为手机要怎么操作才能让锁屏文字滚动起来呢?按照 ...
- 【已解决】小米手机5解BL锁时出现错误码20091怎么办?| 小米手机5怎么解Bootloader锁 | 小米5获取ROOT权限 | 小米手机5卡槽坏了无法正常读取手机卡怎么解锁BL
文章目录 1. 按 2. 问题详细描述 3. 操作步骤 3.1. 确保不是隐藏ID(隐藏)的机器 3.2. 使用高通9008模式降级MIUI 3.3. 使用低版本的MIUI绑定账号 3.4. 使用解锁 ...
最新文章
- 十一月第三周学习进度条
- poj_3067 树状数组
- mysql安装文档_mysql安装文档
- 【大会】QoE也能驱动业务创新
- ddl dml dcl
- 如何查看vantUI官方组件的.vue文件(抛转篇)
- 技术人生:希望有生之年开发一个“自己的解释语言”
- 最新中烟新商盟JS逆向分析实战教程
- 使用.net的Cache框架快速实现Cache操作
- elasticsearch入门(三)
- CMOS电路中闩锁效应产生的原因、过程以及后果
- Android仿微信朋友圈10s视频编辑
- WebSphere 环境搭建
- 清华学霸尹成Python教程
- git:remote: [session-f044bfa6] well: Incorrect username or password (access token)
- CMD/DOS学习笔记
- 人体的神经系统图 分布,神经系统分布图解析图
- DB2错误代码大全(含实际开发中遇到的最多的问题)
- 最新详细版Ubuntu20.04安装教程
- 论文检测平台不同查重结果差异大吗?