博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java多线程编程笔记9:ReentrantReadWriteLock
阅读量:6619 次
发布时间:2019-06-25

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

ReentrantLock具有完全互斥排他的效果,也即同一时间只有一个线程在执行ReentrantLock.lock()方法后边的任务。这样做保证了实例变量的线程安全性,但是效率低下。

ReentrantReadWriteLock类是ReadWriteLock接口的实现类,这是一个读写锁。读写锁维护了两个锁,一个是读相关的,也称之为共享锁;另外一个是写相关的,也叫排他锁。多个读锁之间不排斥,读锁与写锁互斥,写锁与写锁互斥。具体而言,就是多个线程可以同时进行读取操作,但是同一时刻只允许一个线程进行写入操作。

ReentarntReadWriteLock特性

  1. 公平性:默认是公平锁,同时支持非公平锁,吞吐量上来看是非公平优于公平
  2. 重入:支持重进入。读线程在获取读锁后,能再次获取读锁。写线程获取了写锁后能再次获取写锁,也能同时获取读锁。
  3. 锁降级:遵循获取写锁、获取读锁再释放写锁的次序,写锁能降级成为读锁

ReentarntReadWriteLock的使用

读读共享示例代码:

class Service{    private ReentrantReadWriteLock lock=new ReentrantReadWriteLock();    public void read(){        try {            lock.readLock().lock();            System.out.println("获得读锁 "+Thread.currentThread().getName()+" "+new Date(System.currentTimeMillis()));            Thread.sleep(50000);        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.readLock().unlock();        }    }}class MyThread extends Thread{    private Service service;    public MyThread(Service service){        this.service=service;    }    @Override    public void run() {        service.read();    }}public class Run {    public static void main(String[] args) {        Service service=new Service();        MyThread a=new MyThread(service);        a.setName("A");        MyThread b=new MyThread(service);        b.setName("B");        a.start();        b.start();    }}复制代码

运行结果:

获得读锁 B Thu Dec 13 16:09:29 CST 2018获得读锁 A Thu Dec 13 16:09:29 CST 2018复制代码

可以发现,二者是近乎同时进行读取的,也就是读读是共享的。也就是说允许了多个线程同时执行lock()方法后面的代码。

对于写存在的情况,修改代码如下:

class Service{    private ReentrantReadWriteLock lock=new ReentrantReadWriteLock();    public void read(){        try {            lock.readLock().lock();            System.out.println("获得读锁 "+Thread.currentThread().getName()+" "+new Date(System.currentTimeMillis()));            Thread.sleep(5000);        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.readLock().unlock();        }    }    public void write(){        try {            lock.writeLock().lock();            System.out.println("获得写锁 "+Thread.currentThread().getName()+" "+new Date(System.currentTimeMillis()));            Thread.sleep(5000);        } catch (InterruptedException e) {            e.printStackTrace();        } finally {            lock.writeLock().unlock();        }    }}class MyReadThread extends Thread{    private Service service;    public MyReadThread(Service service){        this.service=service;    }    @Override    public void run() {        service.read();    }}class MyWriteThread extends Thread{    private Service service;    public MyWriteThread(Service service){        this.service=service;    }    @Override    public void run() {        service.write();    }}public class Run {    public static void main(String[] args) {        Service service=new Service();        MyReadThread read1=new MyReadThread(service);        read1.setName("read1");        MyReadThread read2=new MyReadThread(service);        read2.setName("read2");        MyWriteThread write1=new MyWriteThread(service);        write1.setName("write1");        MyWriteThread write2=new MyWriteThread(service);        write2.setName("write2");        read1.start();        write1.start();        write2.start();        read2.start();    }}复制代码

运行结果:

获得写锁 write1 Thu Dec 13 16:16:24 CST 2018获得读锁 read1 Thu Dec 13 16:16:29 CST 2018获得写锁 write2 Thu Dec 13 16:16:34 CST 2018获得读锁 read2 Thu Dec 13 16:16:39 CST 2018复制代码

可以看到,四个线程是互斥的执行的,每个线程都是等待了5秒才执行。也就是说,只要出现写操作的过程就是互斥的。

参考资料

  • 高洪岩. Java多线程编程核心技术[M]. 机械工业出版社, 2015

转载地址:http://dsupo.baihongyu.com/

你可能感兴趣的文章
创业杂记——重视自己【序】
查看>>
java面试①整体流程
查看>>
nginx http proxy 正向代理
查看>>
Python type()函数用途及使用方法
查看>>
Swift 静态派发和动态派发
查看>>
BZOJ2002: [Hnoi2010]Bounce 弹飞绵羊(LCT)
查看>>
《从“为什么”开始》听书笔记
查看>>
SQL FORMAT() 函数
查看>>
Adhesive框架系列文章--WCF 分布式服务模块使用和实现
查看>>
BMP_GIF_PNG_LZW_LZ77简介
查看>>
Lucene之IndexWriter的锁机制(备忘)
查看>>
Tracing in ASP.NET Web API
查看>>
objective-c 实现用户验证,登陆 Xcode iOS
查看>>
ACM-博弈论
查看>>
android开源项目-旅游记录
查看>>
Android ListView中按钮监听器设置的解决方案
查看>>
Android 富文本框实现 RichEditText
查看>>
localtime 和 localtime_r
查看>>
多媒体开发之---h264 NALU 语法结构
查看>>
腾讯游戏分享汇:天天飞车六大研发经验
查看>>