java自旋锁使用_实例讲解Java 自旋锁
一直以来不是怎么清楚自旋锁,最近有点时间,好好的学习了一下;
所谓的自旋锁在我的理解就是多个线程在尝试获取锁的时候,其中一个线程获取锁之后,其他的线程都处在一直尝试获取锁的状态,不会阻塞!!!那么什么叫做一直尝试获取锁呢?就是一个循环,比较经典的是AtomicInteger中的一个updateAndGet方法,下图所示(当然也可以直接看unsafe类中的getAndAddInt等类似方法);
我们可以看出在while循环中使用CAS去尝试更新一个变量,如果更新失败,就会一直在这个循环中一直在尝试;成功的话,就可以到最后的return语句;
由此我们可以大概知道如果自旋的线程过多,那么CPU的资源就会被大量消耗!!!
顺便提一个东西叫做原子引用,官方提供了AtomicInteger,AtomicBoolean等原子类,那么如果我们自己定义的类也需要有原子性怎么办呢?所以官方提供了一个AtomicReference类,可以将我们自己定义的类封装一下,就成了我们自己的原子类,例如AtomicReference atomicReference = new AtomicReference<>();,然后我们对Student的实例进行CAS各种CAS操作;
栗子:
package TestMain;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
@Slf4j
public class TestMain80 {
//一个Thread类的原子引用
AtomicReference atomicReference = new AtomicReference<>();
//加锁的方法
public void myLock() {
Thread currentThread = Thread.currentThread();
log.info("myLock--Thread:{}", currentThread.getName());
//这个就是自旋锁的核心,利用CAS比较当前原子引用中是否为null,如果是null,就把当前线程A放到里面去,
// 此时线程B再到这里,那么就会CAS失败,一直在while循环中
while (!atomicReference.compareAndSet(null, currentThread)) {
}
}
//解锁的方法
public void myUnlock() {
Thread currentThread = Thread.currentThread();
//CAS比较原子引用中是不是线程A,是的话就更新为null,此时在上面while中一直在自旋的线程B就可以跳出来了
atomicReference.compareAndSet(currentThread, null);
log.info("myUnlock--Thread:{}", currentThread.getName());
}
public static void main(String[] args) {
TestMain80 testMain80 = new TestMain80();
//线程A,首先加锁,然后等3秒中,然后释放锁
new Thread(() -> {
testMain80.myLock();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
testMain80.myUnlock();
}, "A").start();
//主线程等1秒,保证A线程先执行
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
//线程B,加锁再释放锁
new Thread(() -> {
testMain80.myLock();
testMain80.myUnlock();
}, "B").start();
}
}
上面的就是一个自旋锁的栗子,执行结果中首先是执行A线程的myLock方法,获取锁成功,之后的B线程虽然也会执行mylock方法,但是会在while循环中一直阻塞,直到线程A调用了myUnlock方法释放锁,最后两行才会打印出来;
以上就是实例讲解Java 自旋锁的详细内容,更多关于Java 自旋锁的资料请关注我们其它相关文章!
时间: 2020-09-11
java自旋锁使用_实例讲解Java 自旋锁相关推荐
- java pdf添加图章_实例讲解Java处理PDF图章的方法
图章(印章)是一种在合同.票据.公文等文件中表明法律效应.部门机关权威的重要指示物,常见于各种格式的文件.文档中.对于纸质文档可以手动盖章,但对于电子文档,则需要通过特定的方法来实现.本篇文档分享通过 ...
- java 内部类 加载_举例讲解Java的内部类与类的加载器
内部类 class A { //Inner1 要在 A 初始化后 才能使用,即要被A的对象所调用 class Inner1 { int k = 0; // static int j = 0; //A加 ...
- java console 交互_实例讲解java中Console类的用法
java的Console类的使用方法及实例 java的Console类的使用方法及实例 JDK 6中提供了java.io.Console类专用来访问基于字符的控制台设备.如果你的Java程序要与Win ...
- java 并发 变量_实例讲解Java并发编程之变量
编写线程安全需要关心的: 1.共享的变量 2.可变的变量 共享意味着多个线程可以同时访问,可变意味着其值在生命周期可以改变. 例如以下count 变量: //线程不安全的类 public class ...
- java thread exit方法_实例分析Java终止线程和stop()方法
Java终止线程实例和stop()方法源码阅读 了解线程 概念 线程 是程序中的执行线程.Java 虚拟机允许应用程序并发地运行多个执行线程. 线程特点 拥有状态,表示线程的状态,同一时刻中,JVM中 ...
- java 流的概念_举例讲解Java中的Stream流概念
1.基本的输入流和输出流 流是 Java 中最重要的基本概念之一.文件读写.网络收发.进程通信,几乎所有需要输入输出的地方,都要用到流. 流是做什么用的呢?就是做输入输出用的.为什么输入输出要用&qu ...
- java io 文件复制_实例讲述Java IO文件复制
前言:IO流主要分为两大类,分别是字节流与字符流 注意: 1.音频文件.图片.视频(范围广),就用字节流 2.只涉及到文本的,就用字符流 使用字节流复制文本内容(其他文件也可以) 代码如下: impo ...
- java获取u盘_实例分享java监听u盘的方法
package org.load.u; import java.io.File; import java.util.LinkedHashMap; import java.util.Map; // U盘 ...
- java 动态调用函数_深入讲解Java语言中的函数动态调用方式
相 信 有 不 少 人 使 用C 语 言 的 函 数 指 针 实 现 过 函 数 的 动 态 调 用. 适 当 地 运 用 函 数 动 态 调 用 功 能 不 仅 能 减 少 代 码 数 量, 而 且 ...
最新文章
- 中文地址转英文地址网站_SSL证书可能让你网站源IP地址暴露
- 刚刚,我国智能科学技术最高奖揭晓!
- suse linux 10 ftp服务配置
- 「轻松转换」专业的PDF转换Excel软件:PDF to Excel Converter for Mac
- BZOJ1607 [Usaco2008 Dec]Patting Heads 轻拍牛头 筛法
- docker中使用Mysql8+phpmyadmin
- pom.xml中出现错误提示Failure to transfer org.jboss.weld.jar ... maven2 was cached in the local repository.
- 由方位角和长度如何确定坐标 已知第一个点的坐标
- ubuntu安装nginx-1.11.7
- python爬虫中文乱码解决方法
- lr分析器的设计与实现实验_【重读经典/译文】Facebook广告排序模型:LR+GBDT
- android按钮放图片不显示文字,Android 自定义标签 Imagebutton实现ImageButton里放置文字...
- JAVA 二叉树面试题
- Maven镜像源汇总(含国内、国外)
- 一个月攻克托业--复旦大学考生
- 桌面图标有阴影去除方法
- 被打脸!谁说区块链无落地?这50大落地场景拿走不谢
- 关于对MIDlet套件进行数字签名
- 检测色卡饱和度和色彩偏差
- vue 移动端实现上拉加载更多