自旋锁 是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式去尝试获取锁,这样的好吃是减少线程上下文切换的消耗,缺点是循环会消耗CPU。 
自旋的方式我们在查看AtomicInteger的底层时候就已经体验过了
1 2 3 4 5 6 7 8 9 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; } 
手写自旋锁 首先原子引用线程类AtomicReference<Thread> atomicReference = new AtomicReference<>();
接着编写myLock()首先通过Thread.currentThread();获取到当前线程thread,接着通过原子引用的compareAndSet(null,thread);比较预期值和真实值是否为null,如果为null则更新值为thread,返回true,取反为false退出循环。否则不为null则返回为false,取反为true一直循环,直到为null。从而达到自旋的效果!
myUnLock方法则也是一开始通过Thread.currentThread();获取到当前线程thread,接着通过原子引用的compareAndSet(thread,null);比较预期值和真实值是否为同一个threadl,相同则更新成功为null。(这里解锁方法没有完善,线程没有上锁直接解锁也可以正常执行该方法打印语句退出)
这里优化一下,我们通过对compareAndSet(thread,null);的结果取反做为if的判断条件,只有当compareAndSet(thread,null);的结果为false时,也就是期望与真实值不符时抛出运行时异常throw new RuntimeException("解锁出现了异常!");
当我们直接不上锁而解锁时抛出异常
测试成功,开始正常情况测试!
通过主线程的睡眠,确保每次都是线程A执行,线程A首先获取到自旋锁,接着暂停5秒,在这5秒期间线程B想获取到锁,但是此时的锁在线程A中经过while循环判断不符合,所以线程B一直处于采用循环的方式去尝试获取锁。知道线程A继续开始执行,释放了锁。线程B才能获取到锁并后续将它释放!!
运行验证结果~
代码测试正确!!!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 public  class  SpinLockDemo           AtomicReference<Thread> atomicReference = new  AtomicReference<>();     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();             spinLockDemo.myUnLock();         }, "BB" ).start();     }     public  void  myLock ()           Thread thread = Thread.currentThread();         System.out.println(Thread.currentThread().getName() + "\t come in" );         while  (!atomicReference.compareAndSet(null , thread)) {         }     }     public  void  myUnLock ()           Thread thread = Thread.currentThread();         if  (!atomicReference.compareAndSet(thread, null )){             throw  new  RuntimeException("解锁出现了异常!" );         }         System.out.println(Thread.currentThread().getName() + "\t invoked myUnlock()" );     } }