实现reentrantlock和读写锁
2024-08-29 22:39:25
1 可以手动实现一个类似reentrantlock的工具,首先要维护一个state的标志,代表当前是否有线程已经使用资源。线程lock的时候,
会用cas给state加1,其他线程检测状态。另外需要维护一个等待队列,争夺不到资源的线程统一挂起(park),等线程unlock的时候,
标志减为0,同时从队列里挑一个线程unpark唤醒,继续得到资源操作;如果想让队列线程竞争,就都唤醒,最终只有一个得到资源。
这是实现了基本的锁。
public class LkLock {
private ReentrantLock lock; private Thread ownerThread; private LinkedBlockingQueue<Thread> waitList = new LinkedBlockingQueue<Thread>(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);
}
} }
最新文章
- Android IOS WebRTC 音视频开发总结(六四)-- webrtc能走多远我不知道,但这个市场真实存在
- 加固Samba安全三法
- Leetcode那点事儿
- C++输出hello world 详细注释
- Codeforces 468B Two Sets 并查集
- Javascript的事件委托
- 如何在centos7上安装源码包
- 关于SCSI/SATA/IDE硬盘的比较
- 201521123065《java程序设计》第8周学习总结
- C# CAD批量转换为图片
- 章节四、4-For循环
- python3中 getpass模块使用
- Xcode 8 注释快捷键失效
- 直接将DataTable存入oracle数据库中(转)
- H5上传图片,并且显示进度条
- 对学生排序 Exercise07_17
- linux服务器上创建svn版本库
- hdu 5167(dfs)
- cvCanny的参数
- ";CSRF token missing or incorrect.";的解决方法.