java面试-公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解
一、公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解
公平锁:多个线程按照申请的顺序来获取锁。
非公平锁:多个线程获取锁的先后顺序与申请锁的顺序无关。【ReentrantLock 默认非公平、synchronized】
总结:非公平锁的吞吐量比公平锁大。
可重入锁(又名递归锁):线程可以进入任何一个它已经获取锁的同步代码块中。
可重入锁的最大作用:避免死锁
自旋转:是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁。
好处:减少线程上下文切换的消耗,
缺点:循环会消耗CPU
二、请手写一个自旋锁
/**
* Created by wujuhong on 2019/1/14.
* 通过AtomicReference可实现简单的自旋
*/
public class SpinLock { //原子引用线程
private AtomicReference<Thread> atomicReference = new AtomicReference<>(); //让当前想要获取锁的线程做几个空循环
public void mylock() {
Thread currentThread = Thread.currentThread();
System.out.println(Thread.currentThread().getName()+" come in");
while (!atomicReference.compareAndSet(null, currentThread)) { }
} public void myunlock() {
Thread currentThread = Thread.currentThread();
atomicReference.compareAndSet(currentThread, null);
System.out.println(Thread.currentThread().getName()+" invoked myunlock"); } public static void main(String[] args) {
SpinLock spinLock = new SpinLock();
new Thread(() -> {
spinLock.mylock(); try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
spinLock.myunlock();
},"AA").start(); try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
} new Thread(() -> {
spinLock.mylock();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
spinLock.myunlock();
},"BB").start(); }
}
三、ReentrantReadWriteLock读写锁
- 允许多个线程同时读共享变量
- 只允许一个线程写共享变量
- 如果一个写线程正在执行写操作,此时禁止读线程读共享变量
说明:锁升级不允许,锁降级允许
public class ReadWriteLockDemo {
//写操作:原子+独占,整个过程必须是一个完整的统一体,中间不许被分割,被打断。
public static void main(String[] args) {
MyCache myCache = new MyCache();
for (int i = 0; i <= 5; i++) {
final int tempInt = i;
new Thread(() -> myCache.put(tempInt + "", tempInt), String.valueOf(i)).start();
}
for (int i = 0; i <= 5; i++) {
final int tempInt = i;
new Thread(() -> myCache.get(tempInt + ""), String.valueOf(i)).start();
}
}
}
class MyCache {
private volatile Map<String, Object> map = new HashMap<>();
private ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock();
public void put(String key, Object value) {
rwlock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " 正在写入" + key);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
map.put(key, value);
System.out.println(Thread.currentThread().getName() + " 写入完成");
} finally {
rwlock.writeLock().unlock();
}
}
public void get(String key) {
rwlock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + " 正在读取");
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
Object result = map.get(key);
System.out.println(Thread.currentThread().getName() + " 读取完成" + result);
} finally {
rwlock.readLock().unlock();
}
}
}
java面试-公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解的更多相关文章
- 最全Java锁详解:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁
在Java并发场景中,会涉及到各种各样的锁如公平锁,乐观锁,悲观锁等等,这篇文章介绍各种锁的分类: 公平锁/非公平锁 可重入锁 独享锁/共享锁 乐观锁/悲观锁 分段锁 自旋锁 01.乐观锁 vs 悲观 ...
- Java锁--非公平锁
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3496651.html 参考代码 下面给出Java1.7.0_40版本中,ReentrantLock和AQ ...
- Java中的常见锁(公平和非公平锁、可重入锁和不可重入锁、自旋锁、独占锁和共享锁)
公平和非公平锁 公平锁:是指多个线程按照申请的顺序来获取值.在并发环境中,每一个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程是等待队列的第一个就占有锁,否者就会加入到等待队列中,以 ...
- ReentrantLock可重入锁、公平锁非公平锁区别与实现原理
ReentrantLock是lock接口的一个实现类,里面实现了可重入锁和公平锁非公平锁 ReentrantLock公平锁和不公平锁实现原理 公平锁会获取锁时会判断阻塞队列里是否有线程再等待,若有获取 ...
- “全栈2019”Java多线程第二十九章:可重入锁与不可重入锁详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- Redisson分布式锁学习总结:可重入锁 RedissonLock#lock 获取锁源码分析
原文:Redisson分布式锁学习总结:可重入锁 RedissonLock#lock 获取锁源码分析 一.RedissonLock#lock 源码分析 1.根据锁key计算出 slot,一个slot对 ...
- Java最全锁剖析:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁
乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度,在Java和数据库中都有此概念对应的实际应用. 1.乐观锁 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会 ...
- Java 多线程 -- 理解锁:手动实现可重入锁和不可重入锁
JDK提供的大多数内置锁都是可重入的,也就是 说,如果某个线程试图获取一个已经由它自己持有的锁时,那么这个请求会立 刻成功,并且会将这个锁的计数值加1,而当线程退出同步代码块时,计数器 将会递减,当计 ...
- 【分布式锁】Redis实现可重入的分布式锁
一.前言 之前写的一篇文章<细说分布式锁>介绍了分布式锁的三种实现方式,但是Redis实现分布式锁关于Lua脚本实现.自定义分布式锁注解以及需要注意的问题都没描述.本文就是详细说明如何利用 ...
随机推荐
- TypeScript & global.d.ts
TypeScript & global.d.ts https://www.typescriptlang.org/docs/handbook/declaration-files/template ...
- ng mock服务器数据
angualr文档 in-memory-web-api 文档 安装 yarn add angular-in-memory-web-api -S src/app/app.module.ts import ...
- Mila Fletcher:日常理财应注意的五点
米拉·弗莱彻于2007年毕业于耶鲁大学,她是一名真正意义上的法学博士,在校期间获得了马歇尔奖学金,毕业后曾在美国多家知名律师事务所任职,目前就职于星盟全球投资公司,专注于帮助公司和客户提供法务咨询,他 ...
- 苏黎世财经对话区块链专家,NGK如何利用时间价值实现自身的垂直扩张?
近日,苏黎世财经日报联合法兰西金融等多家知名媒体,专访了NGK. 苏黎世财经日报专栏记者玛科尔德表示,随着NGK DeFi的明星代币BGV登上去中心化金融的舞台,它千倍的收益率让生态投资者趋之若鹜. ...
- 人物传记JULLIAN MURPHY:投资哪家强,区块链必然>股票+房地产
今年上半年在金融股市出现巨大波动的时候,星盟的项目审核经理JULLIAN MURPHY发现了一个有趣的现象:各种熔断和暴跌的背后,特斯拉的股票却从去年年末开始至今已经暴涨了12倍,即便中途有所回落,但 ...
- 「NGK每日快讯」12.31日NGK第58期官方快讯!
- [C#] (原创)一步一步教你自定义控件——06,MaskLayer(遮罩层)
一.前言 技术没有先进与落后,只有合适与不合适. 本篇的自定义控件是:遮罩层(MaskLayer). 遮罩层对软件的美观与易用性上的提高是很大的,在日常使用过程中也会经常看到各种遮罩层,虽然WinFo ...
- Debian 基本使用进阶
系统安装好了我们,迫不及待的想要在Linux系统中肆意翱翔.如果是刚刚接触Linux的系统的话,可能一时间还无法适应Linux的系统环境.对于使用Debian来做服务器的选择,最好的练习方式的就是使用 ...
- 小白养成记——JavaWeb之文件的上传
文件的上传推荐使用commons的fileupload组件来完成.该组件还依赖于io包,因此需要用到两个jar包: commons-fileupload-X.X.jar commons-io-X.X. ...
- deepin 340 USB转console线驱动安装及使用
刚换DEEPIN系统, 有个路由器要做调整,的确是没windows友好,查了网上资料,归总一下. zhaodong@zhaodong-PC:sudo find / -name serial 进入 zh ...