首页 > 编程语言 >【转】-java多线程读写锁ReadWriteLock

【转】-java多线程读写锁ReadWriteLock

时间:2024-07-10 09:43:54浏览次数:19  
标签:缓存 java Thread ReadWriteLock 读写 读锁 lock 多线程

Java多线程中读写锁ReadWriteLock的使用

该博客转载自lavimerJava多线程中读写锁ReadWriteLock的使用

1. 概念

读写锁分为读锁和写锁,多个读锁之间是不需要互斥的(读操作不会改变数据,如果上了锁,反而会影响效率),写锁和写锁之间需要互斥,也就是说,如果只是读数据,就可以多个线程同时读,但是如果你要写数据,就必须互斥,使得同一时刻只有一个线程在操作。

2. 案例

2.1 三线程读数据,三线程写数据

package com.tao.leanrn.thread.lock;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @ClassName ReadWrite
 * @Descriiption 读写锁
 * @Author yanjiantao
 * @Date 2019/8/21 10:42
 **/
public class ReadWrite {

    /**
     * 共享数据
     */
    private int data = 0;

    /**
     * 读写锁
     */
    private ReadWriteLock lock = new ReentrantReadWriteLock();

    public void get() {

        // 上读锁
        lock.readLock().lock();

        try {
            System.out.println(Thread.currentThread().getName() + "----->读锁开始执行...");
            Thread.sleep((long)(Math.random() * 10));
            System.out.println(Thread.currentThread().getName() + "----->读锁得到数据data=" + data);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 释放锁
            lock.readLock().unlock();
        }
    }

    public void set() {

        // 上写锁
        lock.writeLock().lock();

        try {
            System.out.println(Thread.currentThread().getName() + "----->写锁开始执行...");
            Thread.sleep((long)(Math.random() * 10));
            data++;
            System.out.println(Thread.currentThread().getName() + "----->写锁得到数据data=" + data);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 释放写锁
            lock.writeLock().unlock();
        }

    }
}

/**
 * 测试类
 */
class Main{

    public static void main(String[] args) {
        ReadWrite readWrite = new ReadWrite();
        // 创建100个读写线程
        for (int i = 0; i < 100; i++) {
            new Thread(() -> {
                readWrite.get();
            }).start();

            new Thread(() -> {
                readWrite.set();
            }).start();
        }
    }

}

程序运行结果

1706261828185.png

2.2 模拟Hibernate缓存

public class HibernateCache {
 
	/* 定义一个Map来模拟缓存 */
	private Map<String, Object> cache = new HashMap<String, Object>();
 
	/* 创建一个读写锁 */
	private ReadWriteLock rwLock = new ReentrantReadWriteLock();
 
	/**
	 * 模拟Hibernate缓存
	 * @param key
	 * @return
	 */
	private Object getData(String key) {
 
		/* 上读锁 */
		rwLock.readLock().lock();
		/* 定义从缓存中读取的对象 */
		Object value = null;
 
		try {
			/* 从缓存中读取数据 */
			value = cache.get(key);
 
			if (value == null) {
				/* 如果缓存中没有数据,我们就把读锁关闭,直接上写锁【让一个线程去数据库中取数据】 */
				rwLock.readLock().unlock();
				/* 上写锁 */
				rwLock.writeLock().lock();
 
				try {
					/* 上了写锁之后再判断一次【我们只让一个线程去数据库中取值即可,当第二个线程过来的时候,发现value不为空了就去缓存中取值】 */
					if (value == null) {
						/* 模拟去数据库中取值 */
						value = "hello";
					}
				} finally {
					/* 写完之后把写锁关闭 */
					rwLock.writeLock().unlock();
				}
				/* 缓存中已经有了数据,我们再把已经 关闭的读锁打开 */
				rwLock.readLock().lock();
			}
		} finally {
			/* 最后把读锁也关闭 */
			rwLock.readLock().unlock();
		}
		
		return value;
	}
 
}

标签:缓存,java,Thread,ReadWriteLock,读写,读锁,lock,多线程
From: https://www.cnblogs.com/booleandev/p/18293233/turnjava-multithreaded-read-and-write-lock-r

相关文章

  • [Java SE] 字节操作工具类:ByteUtils
    0引言与嵌入式软件数据交互过程中,必然涉及各种的、大量的字节操作场景。如:16进制与10进制、2进制间的转换,字符串、byte数组与int之间的转换等。故此有此核心工具类的沉淀。1ByteUtils依赖<properties> <!--编程提效工具--> <lombok.version>1.18.22</lombok.version>......
  • 【转】-Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
    Java并发编程:CountDownLatch、CyclicBarrier和Semaphore该博客转载自​Matrix海子​的​Java并发编程:CountDownLatch、CyclicBarrier和Semaphore在java1.5中,提供了一些非常有用的辅助类来帮助我们进行并发编程,比如CountDownLatch,CyclicBarrier和Semaphore,今天我们就来学习一下......
  • 【转】-Java并发之CyclicBarrier
    Java并发之CyclicBarrier​ 该博客转载自​巴蜀码哥​**的​Java并发之CyclicBarrier**barrier(屏障)与互斥量、读写锁、自旋锁不同,它不是用来保护临界区的。相反,它跟条件变量一样,是用来协同多线程一起工作的。条件变量是多线程间传递状态的改变来达到协同工作的效果。屏障是......
  • 深入理解Java中的并发编程
    深入理解Java中的并发编程大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!并发编程是Java开发中的一个重要领域,通过并发编程,可以提高程序的执行效率和资源利用率。本文将深入探讨Java中的并发编程,包括线程的创建、同步机制、并发集合、线程池和并发工具类......
  • Java中的垃圾回收机制详解
    Java中的垃圾回收机制详解大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!Java中的垃圾回收(GarbageCollection,GC)机制是Java虚拟机(JVM)管理内存的一项重要功能。GC机制通过自动回收不再使用的对象所占用的内存,防止内存泄漏,提升应用程序的性能和稳定性。......
  • 使用JUnit进行Java单元测试
    使用JUnit进行Java单元测试大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!单元测试是软件开发过程中至关重要的一部分,能够确保代码的正确性、健壮性和可维护性。JUnit是一个流行的Java单元测试框架,广泛应用于Java应用程序的测试。本文将详细介绍如......
  • 如何在Java中处理JSON数据
    如何在Java中处理JSON数据大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式之一。Java提供了多种库来处理JSON数据,最常用的包括Gson、Jackson和org.json等。在本文中,我们将详细介......
  • 【转】-Java CAS 原理剖析
    JavaCAS原理剖析本文转载来自​卡巴拉的树​的​JavaCAS原理剖析在Java并发中,我们最初接触的应该就是synchronized关键字了,但是synchronized属于重量级锁,很多时候会引起性能问题,volatile也是个不错的选择,但是volatile不能保证原子性,只能在某些场合下使用。像synchronized这......
  • 计算机毕业设计项目:18655 课程题库管理系统(开题答辩+程序定制+全套文案 )上万套实战教
    摘 要随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势;对于课程题库管理系统当然也不能排除在外,随着网络技术的不断成熟,带动了课程题库管理系统,它彻底改变了过去传统的管理方式,不仅使服务管理难度变低了,还提升了管理的灵活性。这种个......
  • 计算机毕业设计项目: node.js 网上购物商城的设计与实现99525(开题答辩+程序定制+全套文
    摘 要随着社会的发展,计算机的优势和普及使得网上购物商城的开发成为必需。网上购物商城主要是借助计算机,通过对首页、站点管理(轮播图、公告栏)用户管理(管理员、注册用户)内容管理(商城资讯、资讯分类)商城管理(商城中心、分类列表、订单列表)等信息进行管理。减少管理员的工作......