标签:var5 var1 Thread currentThread var2 自旋 spin
概念和意义
尝试获取锁的线程不会立即阻塞(no wait),而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环消耗cpu
unsafe中的源码
//unsafe.getAndAddInt putlic final int getAndAddInt(Object var1,long var2, int var4){ int var5; do{ var5 = this.getVolatile(var1,var2); }while(!this.compareAndSwapInt(var1,var2,var5,var5+var4)); return var5; }
var1:对象
var2:偏移地址
var5:通过var1和var2得到内存中的变量
会持续获得内存var2中的变量,如果取得的值被修改了,就会重复这一步骤,直到拿到正确的值,然后将值设置为var5+var4。
使用AtomicReference模拟自旋锁
public class SpinLockTest { AtomicReference<Thread> atomicReference = new AtomicReference<>(); // 自定义自旋锁 public void myLock(){ Thread thread = Thread.currentThread(); System.out.println(Thread.currentThread().getName()+"等待拿锁"); while(!atomicReference.compareAndSet(null,thread)){ } System.out.println(Thread.currentThread().getName()+"拿到了"); } // 自定义解锁 public void myUnlock(){ Thread thread = Thread.currentThread(); System.out.println(Thread.currentThread().getName()+"释放了锁"); atomicReference.compareAndSet(thread,null); } public static void main(String[] args) { SpinLockTest spin = new SpinLockTest(); // 线程AA拿锁5秒后释放 new Thread(()->{ spin.myLock(); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } spin.myUnlock(); },"AA").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } // 线程BB尝试拿锁,然后释放 new Thread(()->{ spin.myLock(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } spin.myUnlock(); },"BB").start(); } }
标签:var5,var1,Thread,currentThread,var2,自旋,spin 来源: https://www.cnblogs.com/wsZzz1997/p/14673528.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。