实现自旋锁

什么是自旋锁

它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。

但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。

具体实现

/**
 * @author: code duck
 * @create: 2020-08-31 09:37
 **/
public class SpinLock {

    AtomicReference<Thread> reference = new AtomicReference<>();

    public void lock() {
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName() + "尝试获得锁");

        while (!reference.compareAndSet(null, thread)){
            // 制造循环,阻塞代码.除非当前线程使用unlock()方法调用CAS方法,才会跳出循环
        };
        System.out.println(thread.getName() + "获取到了锁");
    }

    public void unlock() {
        Thread thread = Thread.currentThread();
        reference.compareAndSet(thread, null);
        System.out.println(thread.getName() + "释放锁");
    }

    public static void main(String[] args) {
        SpinLock lock = new SpinLock();
        new Thread(() -> {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + " do something...");
                TimeUnit.SECONDS.sleep(5);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "线程1").start();

        new Thread(() -> {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName() + " do something...");
                TimeUnit.SECONDS.sleep(5);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "线程2").start();
    }
}

程序运行结果:

线程1尝试获得锁
线程2尝试获得锁
线程1获取到了锁
线程1 do something...
线程1释放锁
线程2获取到了锁
线程2 do something...
线程2释放锁
原文地址:https://www.cnblogs.com/code-duck/p/13588021.html