一个自旋锁的栗子
2020-03-21 16:04:34来源:博客园 阅读 ()
一个自旋锁的栗子
一直以来不是怎么清楚自旋锁,最近有点时间,好好的学习了一下;
所谓的自旋锁在我的理解就是多个线程在尝试获取锁的时候,其中一个线程获取锁之后,其他的线程都处在一直尝试获取锁的状态,不会阻塞!!!那么什么叫做一直尝试获取锁呢?就是一个循环,比较经典的是AtomicInteger中的一个updateAndGet方法,下图所示(当然也可以直接看unsafe类中的getAndAddInt等类似方法);
我们可以看出在while循环中使用CAS去尝试更新一个变量,如果更新失败,就会一直在这个循环中一直在尝试;成功的话,就可以到最后的return语句;
由此我们可以大概知道如果自旋的线程过多,那么CPU的资源就会被大量消耗!!!
顺便提一个东西叫做原子引用,官方提供了AtomicInteger,AtomicBoolean等原子类,那么如果我们自己定义的类也需要有原子性怎么办呢?所以官方提供了一个AtomicReference类,可以将我们自己定义的类封装一下,就成了我们自己的原子类,例如AtomicReference<Student> 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<Thread> 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方法释放锁,最后两行才会打印出来;
原文链接:https://www.cnblogs.com/wyq1995/p/12539853.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:不要再写这样的神级代码了!
下一篇:Fork/Join框架简介
- 作为一个面试官,我想问问你Redis分布式锁怎么搞? 2020-06-10
- 我可真是醉了,一个SpringBoot居然问了我30个问题 2020-06-08
- java对象指向问题 2020-06-07
- 呵呵,一个 bug 你改了两天?难吗? 2020-06-06
- 一个程序员的水平能差到什么程度?看到他我明白了! 2020-06-05
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash