JUC —— 读写锁的 使用 和 实例

  • 读写锁概念
  • 读写锁的原理 就是 数据库上的排他锁 和 共享锁
  • 锁升级的原理
  • 代码实例展示
package com.pengshi.ThreadTest;

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

/**
 * @description: 读写锁的概念
 * 	其实我们 要理解 悲观锁 和 乐观锁 的 概念,随便理一下我们出现过所有的锁的概念
 * 	悲观锁 : 就是 我认为 只能有一个线程 进行读写操作
 * 	乐观锁 : 就是 我认为 所有人都可以进行读写,但是对于写操作大部分使用的 CAS 原理,其实 CAS 就是 一种乐观锁的实现原理
 * 	公平锁 : 遵循 FIFO 的等待队列 原理,外部线程进来都是进入等待队列
 * 	非公平锁 : 外部新的线程 可以进行抢占,没有顺序之分,看谁先 拿到 资源
 * 	行锁 : 数据库上的概念,其实就是锁一行的数据,其中 InnoDB 实现就是这种查询方式,锁一行的数据
 * 	表锁 : 数据库上,资源读取,锁住整个表
 * 	共享锁 : 数据库上, 也就是读锁,只允许读操作
 * 	排他锁 : 数据库上,就是只允许一个线程进行操作,进行读写操作
 * 	间隙锁 : 数据库上的概念,进行 数据附近数据前后 加锁
 * 	偏向锁 : JVM 认为 只有某一个线程才会执行同步代码 , 偏向某个线程 进行 运行,但是 其他线程来的时候 会进行尝试修改 CAS 进行修改操作,
 * 			修改 Mark Word 记录的运行线程 Id ,修改成功说明当前线程进行运行, 不成功说明有竞争环境啊,疯狂抢占资源, 此时撤销 偏向锁
 * 			升级为 轻量级锁
 * 	轻量级锁 :
 * 	重量级锁 :
 * 	自旋锁 :不断的 CAS
 *
 * 	其中 后面 几种锁的状态都是 synchronized 的实现原理 ,后续查看本人 blog 进行 更新, 现在看一下 java 的读写锁
 * @projectName: Algorithm
 * @see: com.pengshi.ThreadTest
 * @author: pc
 * @createTime: 2022/2/26 14:45
 * @version: 1.0
 */

class WRLock {
	// volatile 关键字 保证 有序性 和 可见性 一般用在 变量
	// 与之对应的 就是 synchronized 关键字 ,原理 保证了 原子性 和 可见性, 保证 代码块的原子性操作
	private volatile Map<String, String> map = new HashMap<>();

	// public ReentrantReadWriteLock(boolean fair) 自定义是不是公平锁
	private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();


	// 写锁 是 排他锁,只能有一个进去写操作, 所以 我们 只是定义了一个锁 , 所以等待队列进行写操作
	// 读锁 是 共享锁, 所以 任何人可以进去看数据,会发现其中 多个线程一起运行,阻塞 时间不是串行的
	// 读写操作是互斥的 ,也就是 要不 执行 读操作,要么 写操作,但是 读操作 内部 可以重入 ,但是 写操作 不能 重入
	// 读写锁 的 特点 :锁降级, 把 写锁将为读锁, 相当于排他锁变为共享锁, 其实就是 在 写锁 的访问 内 可以加上 读锁的操作,
	// 		没有锁升级 !!!!
	public void put(String str, String str1) {
		readWriteLock.writeLock().lock();

		try {
			System.out.println("进行写操作" + Thread.currentThread().getName());
			Thread.sleep(1000);
			map.put(str, str1);
			System.out.println("写操作完毕" + Thread.currentThread().getName());
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			readWriteLock.writeLock().unlock();
		}
	}

	public String get (String key) {

		readWriteLock.readLock().lock();
		try {
			System.out.println("进行读操作" + Thread.currentThread().getName());
			Thread.sleep(1000);
			String str = map.get(key);
			System.out.println("读操作完毕" + Thread.currentThread().getName() + "数据是" + str);
			return str;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			readWriteLock.readLock().unlock();
		}
		return null;
	}
}
public class WriteAndReadLockTest {
	public static void main(String[] args) {
		WRLock test = new WRLock();
		for (int i = 0; i < 5; ++i) {
			String num = i + "";
			new Thread(() -> {
				test.put(num, "pc牛逼");
			}, String.valueOf(i)).start();
		}

		for (int i = 0; i < 5; ++i) {
			String num = i + "";
			new Thread(() -> {
				test.get(num);
			}, String.valueOf(i)).start();
		}


		// 锁降级
		ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
		readWriteLock.writeLock().lock();

		System.out.println("写操作");

		readWriteLock.readLock().lock();
		System.out.println("读操作");
		readWriteLock.readLock().unlock();

		readWriteLock.writeLock().unlock();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pengshi12138

加油加油

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值