可以回顾之前所说的CAS 自旋锁(spinlock)是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环会消耗CPU 简而言之:一个线程想去获得一个资源,但是该资源暂时获取不到,该线程就会先去做其他事情,过一会再来获取这个资源
一、实现自旋
定义锁
public class SpinLockDemo {AtomicReference<Thread> atomicReference = new AtomicReference<>();// 获取锁public void myLock() {Thread thread = Thread.currentThread();System.out.println(thread.getName() + "--myLock,come in");while (!atomicReference.compareAndSet(null, thread)) {}System.out.println(thread.getName() + "--myLock,get");}// 释放锁public void myUnLock() {Thread thread = Thread.currentThread();atomicReference.compareAndSet(thread, null);System.out.println(thread.getName() + "--myUnLock()");}}
测试
public class SpinLockDemoTest {public static void main(String[] args) {SpinLockDemo spinLockDemo = new SpinLockDemo();new Thread(()->{spinLockDemo.myLock();try {TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace();}spinLockDemo.myUnLock();},"AA").start();try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}new Thread(()->{spinLockDemo.myLock();try {TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }spinLockDemo.myUnLock();},"BB").start();}}结果AA--myLock,come inAA--myLock,getBB--myLock,come inAA--myUnLock()BB--myLock,getBB--myUnLock()
AA线程获取锁之后,等待5秒,在此期间BB线程想要获取锁,由于AA线程尚未释放锁,所以此时BB线程通过循环尝试获取锁。
5秒之后,AA线程释放了锁,此时BB线程拿到了锁。
