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

实现reentrantlock和读写锁的更多相关文章

  1. 多线程并发编程之显示锁ReentrantLock和读写锁

    在Java5.0之前,只有synchronized(内置锁)和volatile. Java5.0后引入了显示锁ReentrantLock. ReentrantLock概况 ReentrantLock是 ...

  2. ReentrantLock和读写锁

    在Java5.0之前,只有synchronized(内置锁)和volatile. Java5.0后引入了显示锁ReentrantLock. ReentrantLock概况 ReentrantLock是 ...

  3. 201709020工作日记--synchronized、ReentrantLock、读写锁

    1.reentrantLock java.util.concurrent.lock 中的Lock 框架是锁定的一个抽象,它允许把锁定的实现作为 Java 类,而不是作为语言的特性来实现.这就为Lock ...

  4. 架构师养成记--14.重入锁ReentrantLock 和 读写锁 ReentrantReadWriteLock

    ReentrantLock 有嗅探锁定和多路分支等功能,其实就是synchronized,wait,notify的升级. this锁定当前对象不方便,于是就有了用new Object()来作为锁的解决 ...

  5. 【漫画】读写锁ReadWriteLock还是不够快?再试试StampedLock!

    本文来源于公众号[胖滚猪学编程] 转载请注明出处! 在互斥锁ReentrantLock不好用?试试读写锁ReadWriteLock一文中,我们对比了互斥锁ReentrantLock和读写锁ReadWr ...

  6. Java并发-显式锁篇【可重入锁+读写锁】

    作者:汤圆 个人博客:javalover.cc 前言 在前面并发的开篇,我们介绍过内置锁synchronized: 这节我们再介绍下显式锁Lock 显式锁包括:可重入锁ReentrantLock.读写 ...

  7. 【漫画】互斥锁ReentrantLock不好用?试试读写锁ReadWriteLock

    ReentrantLock完美实现了互斥,完美解决了并发问题.但是却意外发现它对于读多写少的场景效率实在不行.此时ReentrantReadWriteLock来救场了!一种适用于读多写少场景的锁,可以 ...

  8. 深刨显式锁ReentrantLock原理及其与内置锁的区别,以及读写锁ReentrantReadWriteLock使用场景

    13.显示锁 在Java5.0之前,在协调对共享对象的访问时可以使用的机制只有synchronized和volatile.Java5.0增加了一种新的机制:ReentrantLock.与之前提到过的机 ...

  9. 【java并发编程】ReentrantLock 可重入读写锁

    目录 一.ReentrantLock可重入锁 二.ReentrantReadWriteLock读写锁 三.读锁之间不互斥 欢迎关注我的博客,更多精品知识合集 一.ReentrantLock可重入锁 可 ...

随机推荐

  1. 构造代码块、构造函数、this执行顺序

    一.构造函数 对象一建立就会调用与之对应的构造函数. 构造函数的作用:可以用于给对象进行初始化. 构造函数的小细节:当一个类中没有定义构造函数时,系统会默认给该类加一个空参数的构造函数:当在类中自定义 ...

  2. Spring Cloud之Feign客户端调用工具

    feign介绍 Feign客户端是一个web声明式http远程调用工具,提供了接口和注解方式进行调用. Spring Cloud 支持 RestTemplate  Fetin Feign客户端实际开发 ...

  3. Delphi回调函数的使用-例子

    Delphi回调函数的使用-例子 功能大体描述:Form1中有一个Edit和一个Button,当点击BUTTON时弹出FORM2,FORM2中也有一个EDIT和一个BUTTON,当点击FORM2中的B ...

  4. jQuery创建DOM的方法

    jQuery1.4带来了一个全新的便捷地清晰的DOM对象创建方法,在 jQuery 1.4中,我们可以传递一个对象作为第二个参数. 这个参数接受一个属性的集合,这些可以传递给.attr() 方法.此外 ...

  5. java:Map借口及其子类HashMap五,identityHashMap子类

    java:Map借口及其子类HashMap五,identityHashMap子类 了解:identityHashMap子类 一般情况下,标准的Map,是不会有重复的key值得value的,相同的key ...

  6. django实现用户注册、登录、退出

    视图 from django.contrib import auth from django.contrib.auth.models import User from django.views.dec ...

  7. django1.8.3搭建博客——2 django web 开发指南阅读笔记

    一.    django框架 1 .http封装web服务的整个过程.由请求(request)和响应(response)两部分组成. 请求的内容为URL (指向文档的路径). 响应主要为正文(body ...

  8. 一种解决 MacBook 里的 App Store 无法登录的问题

    刚刚买回来的 2018 款带有 touchbar 的 MacBook Pro 15 inc 在用 App Store 安装 app 时一直无法登录成功(网络链接都是好的),导致软件都无法更新,折腾了挺 ...

  9. rtmp与hls流媒体服务器搭建:ubuntu下Nginx搭建初探与rtmp-module的添加

    关键词:Nignx(http服务器):rtmp,hls(流媒体服务) 前言:感谢开源,感谢战斗民族.现在在做流媒体服务的一些工作,流媒体服务器搭建的网上教程多入牛毛,但是细细查看,发现很多同志贴上来的 ...

  10. UVA12163 游戏

    题目大意 现在有两个人在一个n个结点的有向图上玩一个双人游戏,保证图中无环和自圈.游戏的规则如下:1.初始的时候$i$号点有一个正权值$value_i$2.两名玩家依次操作,每个玩家在当前回合可以选择 ...