Java锁之自旋锁
Java锁之自旋锁
自旋锁:spinlock,是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗CPU
原来提到的比较并交换,底层使用的就是自旋,自旋就是多次尝试,多次访问,不会阻塞的状态就是自旋。

优缺点
优点:循环比较获取直到成功为止,没有类似于wait的阻塞
缺点:当不断自旋的线程越来越多的时候,会因为执行while循环不断的消耗CPU资源
手写自旋锁
通过CAS操作完成自旋锁,A线程先进来调用myLock方法自己持有锁5秒,B随后进来发现当前有线程持有锁,不是null,所以只能通过自旋等待,直到A释放锁后B随后抢到
/**
* 手写一个自旋锁
*
* 循环比较获取直到成功为止,没有类似于wait的阻塞
*
* 通过CAS操作完成自旋锁,A线程先进来调用myLock方法自己持有锁5秒,B随后进来发现当前有线程持有锁,不是null,所以只能通过自旋等待,直到A释放锁后B随后抢到
*/
public class SpinLockDemo {
// 现在的泛型装的是Thread,原子引用线程
AtomicReference<Thread> atomicReference = new AtomicReference<>();
public void myLock() {
// 获取当前进来的线程
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() + "\t come in ");
// 开始自旋,期望值是null,更新值是当前线程,如果是null,则更新为当前线程,否者自旋
while(!atomicReference.compareAndSet(null, thread)) {
}
}
/**
* 解锁
*/
public void myUnLock() {
// 获取当前进来的线程
Thread thread = Thread.currentThread();
// 自己用完了后,把atomicReference变成null
atomicReference.compareAndSet(thread, null);
System.out.println(Thread.currentThread().getName() + "\t invoked myUnlock()");
}
public static void main(String[] args) {
SpinLockDemo spinLockDemo = new SpinLockDemo();
// 启动t1线程,开始操作
new Thread(() -> {
// 开始占有锁
spinLockDemo.myLock();
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 开始释放锁
spinLockDemo.myUnLock();
}, "t1").start();
// 让main线程暂停1秒,使得t1线程,先执行
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 1秒后,启动t2线程,开始占用这个锁
new Thread(() -> {
// 开始占有锁
spinLockDemo.myLock();
// 开始释放锁
spinLockDemo.myUnLock();
}, "t2").start();
}
}
最后输出结果
t1 come in
.....五秒后.....
t1 invoked myUnlock()
t2 come in
t2 invoked myUnlock()
首先输出的是 t1 come in
然后1秒后,t2线程启动,发现锁被t1占有,所有不断的执行 compareAndSet方法,来进行比较,直到t1释放锁后,也就是5秒后,t2成功获取到锁,然后释放
Java锁之自旋锁的更多相关文章
- Java 多线程之自旋锁
一.什么是自旋锁? 自旋锁(spinlock):是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环. 获取锁的线 ...
- java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁(转载)
之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比>,当时对这个测试结果很疑惑,反复执行过多次,发现结果是一样的: 1. 单线程下synchronized效率最高 ...
- java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁
之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比>,当时对这个测试结果很疑惑,反复执行过多次,发现结果是一样的: 1. 单线程下synchronized效率最高 ...
- Java锁---偏向锁、轻量级锁、自旋锁、重量级锁
之前做过一个测试,反复执行过多次,发现结果是一样的: 1. 单线程下synchronized效率最高(当时感觉它的效率应该是最差才对): 2. AtomicInteger效率最不稳定,不同并发情况下表 ...
- Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等
Java 中15种锁的介绍 Java 中15种锁的介绍:公平锁,可重入锁,独享锁,互斥锁,乐观锁,分段锁,自旋锁等等,在读很多并发文章中,会提及各种各样锁如公平锁,乐观锁等等,这篇文章介绍各种锁的分类 ...
- 通俗易懂 悲观锁、乐观锁、可重入锁、自旋锁、偏向锁、轻量/重量级锁、读写锁、各种锁及其Java实现!
网上关于Java中锁的话题可以说资料相当丰富,但相关内容总感觉是一大串术语的罗列,让人云里雾里,读完就忘.本文希望能为Java新人做一篇通俗易懂的整合,旨在消除对各种各样锁的术语的恐惧感,对每种锁的底 ...
- 写文章 通俗易懂 悲观锁、乐观锁、可重入锁、自旋锁、偏向锁、轻量/重量级锁、读写锁、各种锁及其Java实现!
网上关于Java中锁的话题可以说资料相当丰富,但相关内容总感觉是一大串术语的罗列,让人云里雾里,读完就忘.本文希望能为Java新人做一篇通俗易懂的整合,旨在消除对各种各样锁的术语的恐惧感,对每种锁的底 ...
- java多线程之锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁
转载至:https://blog.csdn.net/zqz_zqz/article/details/70233767 之前做过一个测试,详情见这篇文章<多线程 +1操作的几种实现方式,及效率对比 ...
- Java锁之乐观锁、悲观锁、自旋锁
java锁分为三大类乐观锁.悲观锁.自旋锁 乐观锁:乐观锁是一种乐观思想,即认为读多写少,遇到并发写的可能性低,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别 ...
随机推荐
- Python python 五种数据类型--字典
# 定义一个字典 var1 = {'a':20,'b':40}; var2 = dict(); print(type(var1)) print(type(var2)) # 长度 length = le ...
- 数字反转 NOIp普及组2011
当数字位数不确定时,如何反转呢? 本文为博客园ShyButHandsome原创作品,转载请注明出处 使用右侧目录快速浏览文章 题目描述 给定一个整数,请将该数各个位上数字反转得到一个新数. 新数也应满 ...
- 树莓派 Raspberry PI之GPIO
树莓派 Raspberry PI之GPIO 树莓派各版本硬件原理图:https://www.raspberrypi.org/documentation/hardware/raspberrypi/REA ...
- coderforces Gym 100803A/Aizu 1345/CSU 1536/UVALive 6832 Bit String Reordering(贪心证明缺)
Portal: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1345 http://codeforces.com/gym/100 ...
- 使用Gitee搭建个人图床
使用Gitee搭建个人图床 一.前言 搭建个人的图床可以更加方便地管理个人图片,虽然Github也可以实现个人图床的搭建,但是,Github毕竟是外网,访问速度慢且不稳定.因此采用Gitee来搭建图床 ...
- html5 css写出一个实心三角形和空心三角行
原理:css中的border属性的特殊性. 实心三角形: html5: <div id="mydiv"></div> css: #mydiv{ height ...
- eolinker测试增强
地址:https://www.eolinker.com Chrome: https://chrome.google.com/webstore/detail/eolinker/mdbgchaihbacj ...
- Linux命令 dos2unix 的实际应用场景
问题描述:书接上文springboot之停止与启动服务的脚本,编写杀死服务脚本的时候,总是不行,Linux会提示你类似下面这样的信息: killed pid: : arguments must be ...
- Haystack+ES解决搜索服务
最近项目组需要对老的搜索项目进行迁移和改造,刚入职2个星期的我光荣的接受了这份工作,这也是我第一次接触Haystack和Elasticsearch,以下是记录下工作中的一些需求解决,具体haystac ...
- java对于目录下的相关文件的单词操作
写入文件的目录.代码通过找目录下的文件,进行相关函数的操作.如果目录下面包含子目录.代码设有调用递归的方法,在寻找子目录下的文件 在进行相关的函数操作.函数主要是按用户输入的个数要求输出文件中出现次数 ...