读写锁ReentrantReadWriteLock

ReentrantLock无论是“写/写”线程、“读/读”线程、“读/写”线程之间的工作都是互斥,同一 时间只有一个线程能进入同步区域。然而大多实际场景是“读/读”线程间并不存在互斥关系,只有"读/写"线程或"写/写"线程间的操作需要互斥的。

ReentrantReadWriteLock特性:

 一个资源可以被多个读操作同时访问,而只能对一个写操作访问,但读和写两者不能同时进行。

从而提高读操作的吞吐量。

使用场景:对于读多写少的场景使用ReentrantReadWriteLock 性能会比ReentrantLock高出不少。

在多线程读时互不影响,不像ReentrantLock即使是多线程读也需要每个线程获取锁。不过任何一个线程在写的时候就和ReentrantLock类似,其他线程无论读还是写都必须获取锁。

需要注意的是同一个线程可以拥有 writeLock readLock (但必须先获取 writeLock 再获取 readLock, 反过来进行获取会导致死锁)

默认构造方法为 非公平模式 ,开发者也可以通过指定构造方法传参数true设置为 公平模式。

读锁的条件直接调用ReentrantReadWriteLock的 newCondition 会直接exception public Condition newCondition() {

throw new UnsupportedOperationException();

}

 

package com.lock;

import org.apache.log4j.Logger;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁
 */
public class LockTest6 {
     static Logger log = Logger.getLogger(LockTest6.class);
      static ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
      //读锁
      static Lock r = rwl.readLock();
      //写锁
      static Lock w = rwl.writeLock();


    public static void main(String[] args) throws InterruptedException {

        //读
        new Thread("读线程1 "){
            public void run(){
                log.debug("read1 获取 锁");
                r.lock();
                try {
                    for (int i = 0; i < 10; i++) {
                        m1(i);
                    }
                }finally {
                    r.unlock();
                }
            }
        }.start();

      //写
        new Thread("写线程--"){
            public void run(){
                log.debug("write 获取 锁");
                w.lock();
                try {
                    for (int i = 0; i < 20; i++) {
                        m1(i);
                    }
                }finally {
                    w.unlock();
                }
            }
        }.start();


        //读
        new Thread("读线程2"){
            public void run(){
                log.debug("read2 获取 锁");
                r.lock();
                try {
                    for (int i = 0; i < 20; i++) {
                        m1(i);
                    }
                }finally {
                    r.unlock();
                }

            }
        }.start();

    }


    public static void m1(int i){
            log.debug(Thread.currentThread().getName()+"执行任务 "+i);
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

1:两个读线程可以并发访问,而写线程只能独自访问(独占)

2:读写支持重入但是只支持降级不止升级

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值