MENU

Java面试题自旋锁

• May 5, 2020 • Read: 96 • Note,JUC

自旋锁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 {

    /**
     * 原子引用线程
     */
    AtomicReference<Thread> atomicReference = 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释放锁。

这就是自旋锁的妙处。


本站所有未注明转载的文章均为原创,并采用CC BY-NV-SA 4.0 授权协议,转载请注明来源。

Last Modified: May 8, 2020
Archives QR Code
QR Code for this page
Tipping QR Code
Leave a Comment

2 Comments
  1. 看到Java就头疼,大佬们都是如何学习的啊。我学Java巨吃力

    1. @Escher这个,我感觉Java用起来比前端轻松得多,::quyin:amazing:: 应该是各有喜好无需强求。