博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
实现reentrantlock和读写锁
阅读量:4331 次
发布时间:2019-06-06

本文共 2879 字,大约阅读时间需要 9 分钟。

1 可以手动实现一个类似reentrantlock的工具,首先要维护一个state的标志,代表当前是否有线程已经使用资源。线程lock的时候,
会用cas给state加1,其他线程检测状态。另外需要维护一个等待队列,争夺不到资源的线程统一挂起(park),等线程unlock的时候,
标志减为0,同时从队列里挑一个线程unpark唤醒,继续得到资源操作;如果想让队列线程竞争,就都唤醒,最终只有一个得到资源。
这是实现了基本的锁。
public class LkLock {
private ReentrantLock lock;     private Thread ownerThread;     private LinkedBlockingQueue
waitList = new LinkedBlockingQueue
(10000); private static Unsafe unsafe =null; private int state=0; private static long stateOffset; public LkLock(){
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe"); //Internal reference  f.setAccessible(true); unsafe = (Unsafe) f.get(null); stateOffset= unsafe.objectFieldOffset(LkLock.class.getDeclaredField("state")); } catch (Exception e) {
System.out.println(e+" error"); } } public void lock(){
if(compareAndSetState(0,1)){
ownerThread=Thread.currentThread(); }else{
acquire(1); } } public void unlock(){
compareAndSetState(1,0); if(!CollectionUtils.isEmpty(waitList)){
Thread t=waitList.poll(); LockSupport.unpark(t); } } private void acquire(int i){
try {
//加入等待队列  waitList.put(Thread.currentThread()); //挂起  LockSupport.park(); } catch (InterruptedException e) {
System.out.println(e); } } public int getState() {
return state; } private boolean compareAndSetState(int src, int target){
return unsafe.compareAndSwapInt(this, stateOffset, src, target); } }

2  同样 如果想要实现能够重入的读写锁,读可重入,写唯一,并且读写互斥,那么需要用两个资源分别给读写的线程竞争,

读的资源可累加,每次线程readlock的时候加一,不设上限;写的线程如上面只可唯一线程获得资源。并且无论读写线程竞争资源之前,

都要检测对方资源是否已经被占用,如果占用也要挂起,这样可以达到互斥。改动如下 

public void readLock(){
if(writeState!=0){
acquire(); } if(compareAndSetReadState(readState,readState+1)){
System.out.println(readState+" 读 我看到的 "+Thread.currentThread()); }else{
acquire(); } } public void readUnlock(){
compareAndSetReadState(readState,readState-1); if(!CollectionUtils.isEmpty(waitList)){
while (waitList.size()!=0){
Thread t=waitList.poll(); LockSupport.unpark(t); } } } public void writeLock(){
if(readState!=0){
acquire(); } if(compareAndSetWriteState(0,1)){
System.out.println(writeState+" 写 我看到的 "+Thread.currentThread()); }else{
acquire(); } } public void writeUnlock(){
compareAndSetWriteState(1,0); if(!CollectionUtils.isEmpty(waitList)){
while (waitList.size()!=0){
Thread t=waitList.poll(); LockSupport.unpark(t); } } }

 

转载于:https://www.cnblogs.com/lkdirk/p/6627738.html

你可能感兴趣的文章
Python中and(逻辑与)计算法则
查看>>
POJ 3267 The Cow Lexicon(动态规划)
查看>>
设计原理+设计模式
查看>>
音视频处理
查看>>
tomcat 7服务器跨域问题解决
查看>>
前台实现ajax 需注意的地方
查看>>
Jenkins安装配置
查看>>
个人工作总结05(第二阶段)
查看>>
Java clone() 浅拷贝 深拷贝
查看>>
深入理解Java虚拟机&运行时数据区
查看>>
02-环境搭建
查看>>
spring第二冲刺阶段第七天
查看>>
搜索框键盘抬起事件2
查看>>
阿里百川SDK初始化失败 错误码是203
查看>>
透析Java本质-谁创建了对象,this是什么
查看>>
BFS和DFS的java实现
查看>>
关于jquery中prev()和next()的用法
查看>>
一、 kettle开发、上线常见问题以及防错规范步骤
查看>>
eclipse没有server选项
查看>>
CRC码计算及校验原理的最通俗诠释
查看>>