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);
}
} }

最新文章

  1. Android IOS WebRTC 音视频开发总结(六四)-- webrtc能走多远我不知道,但这个市场真实存在
  2. 加固Samba安全三法
  3. Leetcode那点事儿
  4. C++输出hello world 详细注释
  5. Codeforces 468B Two Sets 并查集
  6. Javascript的事件委托
  7. 如何在centos7上安装源码包
  8. 关于SCSI/SATA/IDE硬盘的比较
  9. 201521123065《java程序设计》第8周学习总结
  10. C# CAD批量转换为图片
  11. 章节四、4-For循环
  12. python3中 getpass模块使用
  13. Xcode 8 注释快捷键失效
  14. 直接将DataTable存入oracle数据库中(转)
  15. H5上传图片,并且显示进度条
  16. 对学生排序 Exercise07_17
  17. linux服务器上创建svn版本库
  18. hdu 5167(dfs)
  19. cvCanny的参数
  20. &quot;CSRF token missing or incorrect.&quot;的解决方法.

热门文章

  1. 用cocos2d-html5做的消除类游戏《英雄爱消除》——概述
  2. Mysql的空值与NULL的区别
  3. mysql 数据库备份方案及策略
  4. jQuery悬浮焦点图宽屏
  5. 20145229吴姗珊《Java程序设计》2天总结
  6. 算法(Algorithms)第4版 练习 1.5.22
  7. Hadoop- HDFS的API操作
  8. OTSU大津法对图像二值化
  9. 数据库+maven
  10. C#子线程执行完后通知主线程