ReadLock和WriteLock(读写锁) 您所在的位置:网站首页 kazoo怎么读 ReadLock和WriteLock(读写锁)

ReadLock和WriteLock(读写锁)

2023-12-10 02:38| 来源: 网络整理| 查看: 265

ReadWriteLock也是一个接口,提供了readLock和writeLock两种锁的操作机制,一个资源可以被多个线程同时读,或者被一个线程写,但是不能同时存在读和写线程。

使用场合

假设在程序中定义一个共享的数据结构用作缓存,它大部分时间提供读服务(例如:查询和搜索),而写操作占有的时间很少,但是写操作完成之后的更新需要对后续的读服务可见。

在没有读写锁支持的(Java 5 之前)时候,如果需要完成上述工作就要使用Java的等待通知机制,就是当写操作开始时,所有晚于写操作的读操作均会进入等待状态,只有写操作完成并进行 通知之后,所有等待的读操作才能继续执行(写操作之间依靠synchronized关键字进行同步),这样做的目的是使读操作都能读取到正确的数据,而不会出现脏读。改用读写锁实现上述功能,只需要在读操作时获取读锁,而写操作时获取写锁即可,当写锁被获取到时,后续(非当前写操作线程)的读写操作都会被 阻塞,写锁释放之后,所有操作继续执行,编程方式相对于使用等待通知机制的实现方式而言,变得简单明了。

特性

ReentrantReadWriteLock的实现里面有以下几个特性

**1、公平性:非公平锁(默认)。**读线程之间没有锁操作,所以读操作没有公平性和非公平性。写操作时,由于写操作可能立即获取到锁,所以会推迟一个或多个读操作或者写操作。非公平锁的吞吐量要高于公平锁。(公平锁概念:公平锁利用AQS的CLH队列,释放当前保持的锁时,优先为等待时间最长的那个写操作分配写入锁) **2、重入性:**读写锁允许读线程和写线程按照请求锁的顺序重新获取读取锁或者写入锁。只有写线程释放了锁,读线程才可以获取重入锁,写线程获取写入锁后可以再次获取读取锁,但是读线程获取读取锁后却不能获取写入锁。 **3、锁降级:**写线程获取写入锁后可以获取读取锁,然后释放写入锁,这样就从写入锁变成了读取锁,从而实现锁降级特性,经典cache案例使用了锁降级 **4、锁升级:**读取锁是不能直接升级为写入锁的。因此获取一个写入锁需要先释放所有的读取锁,如果有两个读取锁试图获取写入锁,且都不释放读取锁时,就会发生死锁 **5、锁获取中断:**读取锁和写入锁都支持获取锁期间被中断 **6、条件变量:**写入锁提供了条件变量的支持,但是读取锁却不允许获取条件变量,否则会得到一个UnsupportedOperationExcetpion异常 **7、重入锁:**读取锁和写入锁的数量最大分别只能是65535

读写锁机制

读-读不互斥

读-写互斥

写-写互斥

示例代码:

import java.util.concurrent.locks.ReentrantReadWriteLock; public class ReadWriteLockTest { private double data = 0; ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); public void get(){ try { rwl.readLock().lock(); System.out.println("----Thread:"+Thread.currentThread().getName()+"----read first value:"+data); Thread.sleep(1000); System.out.println("----Thread:"+Thread.currentThread().getName()+"----read second value:"+data); rwl.readLock().unlock(); } catch (Exception e) { // TODO: handle exception } } public void put(){ try { rwl.writeLock().lock(); data = Math.random(); System.out.println("----Thread:"+Thread.currentThread().getName()+"----write first value:"+data); Thread.sleep(100); rwl.writeLock().unlock(); } catch (Exception e) { // TODO: handle exception } } } public class MainReadWritLockTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub final ReadWriteLockTest rwlt = new ReadWriteLockTest(); for(int i=0; i


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有