Java - 自旋锁(spinlock)

理论 – 代码 – 小总结

Java - 自旋锁(spinlock)

是指尝试获取锁的线程不会立即阻塞,而是采用 循环 的方式 尝试获取锁,这样的好处是减少线程上下文切换的消耗,
缺点是会消耗 CPU。

例如:AtomicInteger 的 getAndIncrement() 方法中通过 Unsafe 的 compareAndSwapInt() 方法 类似自旋的方式

private static final Unsafe unsafe = Unsafe.getUnsafe();

public final int getAndIncrement() {
     
    return unsafe.getAndAddInt(this, valueOffset, 1);
}

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.test.mianshi.lock.自旋锁;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 手写自旋锁
 */
public class SpinLockDemo {
     

    private AtomicReference<Thread> atomicReference = new AtomicReference<>();

    public void myLock() {
     
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName() + " come in。。。");
        // 原子引用在初始化后,当前存储的值为 null,第一次比较时,可以完成比较并交换
        while (!atomicReference.compareAndSet(null, thread)) {
     

        }
    }

    public void myUnLock() {
     
        Thread thread = Thread.currentThread();
        atomicReference.compareAndSet(thread, null);
        System.out.println(Thread.currentThread().getName() + "\t invoked myUnLock()");
    }

    public static void main(String[] args) {
     
        SpinLockDemo spinLockDemo = new SpinLockDemo();
        new Thread(()->{
     
            spinLockDemo.myLock();
            try {
     TimeUnit.SECONDS.sleep(3);}catch (InterruptedException e) {
     }
            spinLockDemo.myUnLock();
        }, "t1").start();

        new Thread(()->{
     
            spinLockDemo.myLock();
            try {
     TimeUnit.SECONDS.sleep(1);}catch (InterruptedException e) {
     }
            spinLockDemo.myUnLock();
        }, "t2").start();
    }
}

打印结果:

t2 come in。。。
t1 come in。。。
t2	 invoked myUnLock()
t1	 invoked myUnLock()

t1 come in。。。
t2 come in。。。
t1	 invoked myUnLock()
t2	 invoked myUnLock()

你可能感兴趣的:(java锁机制,并发编程)