一、公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解

公平锁:多个线程按照申请的顺序来获取锁。

非公平锁:多个线程获取锁的先后顺序与申请锁的顺序无关。【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面试-公平锁/非公平锁/可重入锁/递归锁/自旋锁谈谈你的理解的更多相关文章

  1. 最全Java锁详解:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁

    在Java并发场景中,会涉及到各种各样的锁如公平锁,乐观锁,悲观锁等等,这篇文章介绍各种锁的分类: 公平锁/非公平锁 可重入锁 独享锁/共享锁 乐观锁/悲观锁 分段锁 自旋锁 01.乐观锁 vs 悲观 ...

  2. Java锁--非公平锁

    转载请注明出处:http://www.cnblogs.com/skywang12345/p/3496651.html 参考代码 下面给出Java1.7.0_40版本中,ReentrantLock和AQ ...

  3. Java中的常见锁(公平和非公平锁、可重入锁和不可重入锁、自旋锁、独占锁和共享锁)

    公平和非公平锁 公平锁:是指多个线程按照申请的顺序来获取值.在并发环境中,每一个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者当前线程是等待队列的第一个就占有锁,否者就会加入到等待队列中,以 ...

  4. ReentrantLock可重入锁、公平锁非公平锁区别与实现原理

    ReentrantLock是lock接口的一个实现类,里面实现了可重入锁和公平锁非公平锁 ReentrantLock公平锁和不公平锁实现原理 公平锁会获取锁时会判断阻塞队列里是否有线程再等待,若有获取 ...

  5. “全栈2019”Java多线程第二十九章:可重入锁与不可重入锁详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  6. Redisson分布式锁学习总结:可重入锁 RedissonLock#lock 获取锁源码分析

    原文:Redisson分布式锁学习总结:可重入锁 RedissonLock#lock 获取锁源码分析 一.RedissonLock#lock 源码分析 1.根据锁key计算出 slot,一个slot对 ...

  7. Java最全锁剖析:独享锁/共享锁+公平锁/非公平锁+乐观锁/悲观锁

    乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度,在Java和数据库中都有此概念对应的实际应用. 1.乐观锁 顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会 ...

  8. Java 多线程 -- 理解锁:手动实现可重入锁和不可重入锁

    JDK提供的大多数内置锁都是可重入的,也就是 说,如果某个线程试图获取一个已经由它自己持有的锁时,那么这个请求会立 刻成功,并且会将这个锁的计数值加1,而当线程退出同步代码块时,计数器 将会递减,当计 ...

  9. 【分布式锁】Redis实现可重入的分布式锁

    一.前言 之前写的一篇文章<细说分布式锁>介绍了分布式锁的三种实现方式,但是Redis实现分布式锁关于Lua脚本实现.自定义分布式锁注解以及需要注意的问题都没描述.本文就是详细说明如何利用 ...

随机推荐

  1. perl 在windows上获取当前桌面壁纸

    更多 #!/usr/bin/perl # 在windows获取当前的桌面壁纸 # See also: https://www.winhelponline.com/blog/find-current-w ...

  2. 手写一个webpack,看看AST怎么用

    本文开始我会围绕webpack和babel写一系列的工程化文章,这两个工具我虽然天天用,但是对他们的原理理解的其实不是很深入,写这些文章的过程其实也是我深入学习的过程.由于webpack和babel的 ...

  3. Promise和async await详解

    本文转载自Promise和async await详解 Promise 状态 pending: 初始状态, 非 fulfilled 或 rejected. fulfilled: 成功的操作. rejec ...

  4. java: 类 RegisterController 是公共的, 应在名为 RegisterController.java 的文

    public声明的类名需要和文件名一致,检查一下

  5. 微信小程序引入ECharts组件

    首先打开ECharts网页 https://echarts.apache.org/zh/tutorial.html#%E5%9C%A8%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8 ...

  6. Hi3559AV100外接UVC/MJPEG相机实时采图设计(二):V4L2接口的实现(以YUV422为例)

    下面将给出Hi3559AV100外接UVC/MJPEG相机实时采图设计的整体流程,主要实现是通过V4L2接口将UVC/MJPEG相机采集的数据送入至MPP平台,经过VDEC.VPSS.VO最后通过HD ...

  7. 医学图像 | DualGAN与儿科超声心动图分割 | MICCAI

    文章转自微信公众号:「机器学习炼丹术」 作者:炼丹兄(已授权) 联系方式:微信cyx645016617(欢迎交流共同进步) 论文名称:"Dual Network Generative Adv ...

  8. Java变量-常量-作用域

    public class Demo05 { /* 变量的命名规范:见名知意 1.类变量/实例变量/局部变量使用驼峰原则命名 2.类名使用Pascal命名法 3.常量名使用大写字母和下划线 4.驼峰原则 ...

  9. 设计模式系列之享元模式(Flyweight Pattern)——实现对象的复用

    说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...

  10. 如何获取下载 FreeBSD

    『如何获取下载 FreeBSD 』 『如何获取下载 FreeBSD 』 FreeBSD 是免费获取的. [下载地址] O网页链接 版本选择,尽量选择较新版本,桌面用户可选择 current 版本.st ...