首页 > 程序开发 > 软件开发 > Java > 正文
Java并发框架——AQS阻塞队列管理(二)
2014-12-22       个评论    来源:wangyangzhizhou的专栏  
收藏    我要投稿
看Craig, Landin, and Hagersten发明的CLH锁如何优化同步带来的花销,其核心思想是:通过一定手段将所有线程对某一共享变量轮询竞争转化为一个线程队列且队列中的线程各自轮询自己的本地变量。这个转化过程由两个要点,一是构建怎样的队列&如何构建队列,为了保证公平性,构建的将是一个FIFO队列,构建的时候主要通过移动尾部节点tail实现队列的排队,每个想获取锁的线程创建一个新节点并通过CAS原子操作将新节点赋予tail,然后让当前线程轮询前一节点的某个状态位,如图2-5-9-3,如此就成功构建线程排队队列;二是如何释放队列,执行完线程后只需将当前线程对应的节点状态位置为解锁状态,由于下一节点一直在轮询,可获取到锁。
\
图2-5-9-3 CLH锁
CLH锁的核心思想貌似是将众多线程长时间对某资源的竞争,通过有序化这些线程转化为只需对本地变量检测。唯一存在竞争的地方就是在入队列之前对尾节点tail的竞争,但竞争的线程的数量已经少了很多,且比起所有线程直接对某资源竞争的轮询次数也减少了很多,节省了很多CPU缓存同步操作,大大提升系统性能,利用空间换取性能。下面提供一个简单的CLH锁实现代码,lock与unlock两方法提供加锁解锁操作,每次加锁解锁必须将一个CLHNode对象作为参数传入,lock方法的fZ喎"/kf/ware/vc/" target="_blank" class="keylink">vctGtu7fKx82ouf1DQVOy2df3vavQwr3ateOy5cjrttPB0KOstvh3aGlsZdGtu7fU8srHvOyy4sewx/292rXjtcTL+Ne0zKzOu6Os0ru1qcewx/292rXjy/jXtMyszrvUytDt1PK94cr4vOyy4sjDz9+zzM35z8LWtNDQoaO94sv4stnX98/IxdC2z7Wxx7C92rXjyse38c6qzrK92rXjo6zI58rH1PLWsb3TvavOsr3atePWw86qv9WjrLTLyrHLtcP7vfa99ta709DSu8z1z9+zzNTa1rTQ0KOst/HU8r2rtbHHsL3ateO1xMv417TMrM671sPOqr3iy/jXtMysoaM8YnI+Cjxicj4KPGJyPgpwdWJsaWMgY2xhc3MgQ0xITG9jayB7PGJyPgo8YnI+Cjxicj4KcHJpdmF0ZSBzdGF0aWMgVW5zYWZlIHVuc2FmZSA9IG51bGw7PGJyPgpwcml2YXRlIHN0YXRpYyBmaW5hbCBsb25nIHZhbHVlT2Zmc2V0Ozxicj4KcHJpdmF0ZSB2b2xhdGlsZSBDTEhOb2RlIHRhaWw7PGJyPgpwdWJsaWMgY2xhc3MgQ0xITm9kZSB7PGJyPgpwcml2YXRlIGJvb2xlYW4gaXNMb2NrZWQgPSB0cnVlOzxicj4KfTxicj4KPGJyPgo8YnI+CnN0YXRpYyB7PGJyPgp0cnkgezxicj4KdW5zYWZlID0gZ2V0VW5zYWZlSW5zdGFuY2UoKTs8YnI+CnZhbHVlT2Zmc2V0ID0gdW5zYWZlLm9iamVjdEZpZWxkT2Zmc2V0KENMSExvY2suY2xhc3M8YnI+Ci5nZXREZWNsYXJlZEZpZWxkKA=="tail"));
} catch (Exception ex) {
throw new Error(ex);
}
}


public void lock(CLHNode currentThreadNode) {
CLHNode preNode = null;
for (;;) {
preNode = tail;
if (unsafe.compareAndSwapObject(this, valueOffset, tail,
currentThreadNode))
break;
}
if (preNode != null)
while (preNode.isLocked) {
}
}


public void unlock(CLHNode currentThreadNode) {
if (!unsafe.compareAndSwapObject(this, valueOffset, currentThreadNode,null))
currentThreadNode.isLocked = false;
}


private static Unsafe getUnsafeInstance() throws SecurityException,
NoSuchFieldException, IllegalArgumentException,
IllegalAccessException {
Field theUnsafeInstance = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeInstance.setAccessible(true);
return (Unsafe) theUnsafeInstance.get(Unsafe.class);
}


}
点击复制链接 与好友分享!回本站首页
相关TAG标签 队列 框架
上一篇:12-21java面向对象之异常
下一篇:将某一个路径下的所有java文件复制到另外一个文件夹下,并重命名为jad文件
相关文章
图文推荐
文章
推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训
版权所有: 红黑联盟--致力于做实用的IT技术学习网站