Java面试题自旋锁
小编:艳芬 1133阅读 2020.09.11
自旋锁spinlock
重点:尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,不会堵塞。缺点是循环会消耗CPU
public final int getAndAddInt(Object var1, long var2, int var4) { int var5; do { var5 = this.getIntVolatile(var1, var2); } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); return var5; }手敲自旋锁:
代码:
package com.juc.lock; import java.util.Date; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; /** * Created by 乐心湖 on 2020/5/5 19:49 */ public class SpinLockDemo { /** * 原子引用线程 */ AtomicReferenceatomicReference = new AtomicReference<>(); /** * 自己写一个锁 */ public void myLock() { Thread thread = Thread.currentThread(); System.out.println(thread.getName() + "\t come in !" + new Date()); // 交换不成功则一直自旋 while (!atomicReference.compareAndSet(null, thread)) { } } /** * 解锁 */ public void myUnLock() { Thread thread = Thread.currentThread(); atomicReference.compareAndSet(thread, null); System.out.println(thread.getName() + "\t go out !" + new Date()); } public static void main(String[] args) { SpinLockDemo spinLockDemo = new SpinLockDemo(); new Thread(() -> { spinLockDemo.myLock(); try { // 线程1在6秒后才释放锁 TimeUnit.SECONDS.sleep(6); } catch (InterruptedException e) { e.printStackTrace(); } spinLockDemo.myUnLock(); }, "Thread1").start(); // 等两秒才开始线程2 try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { spinLockDemo.myLock(); spinLockDemo.myUnLock(); }, "Thread2").start(); } }
Thread1 come in !Tue May 05 20:02:54 CST 2020 Thread2 come in !Tue May 05 20:02:56 CST 2020 Thread1 go out !Tue May 05 20:03:00 CST 2020 Thread2 go out !Tue May 05 20:03:00 CST 2020
从结果可以看出,在线程1还没有释放锁时,线程2无法执行操作,仅仅是进入后不断循环直到线程1释放锁。
这就是自旋锁的妙处。
相关推荐
- 2021年美团程序员面试题 第1题: k链表翻转。给出一个链表和一个数k,比如链表1→2→3→4→5→6,k=2,则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6,用程序实现。 typedef struct node { struct node *next; int data;} node;void…
- 整理+学习《Java面试题全集(上)》 1、面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面:抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。继承:继承是从已有类得到继承…
- 3DMAX提示和技巧 本主题标识使用 Civil View 的一些重要提示和技巧。常规使用屏幕分辨率至少为 1280x1024 的 Civil View。低于此分辨率时,一些面板将占用过多屏幕空间。 将视口设置为线框显示以达到最佳性能。 要尽可能简化用户界面,请在单个视口中工作并关闭 3ds Max 命令面…