目录

​​一、ReadWriteLock读写锁​​

​​1、概述​​

​​官方文档介绍:​​

​​2、问题引出​​

​​代码实现:​​

​​运行结果:​​

​​问题:​​

​​3、使用读写锁​​

​​代码实现:​​

​​运行结果:​​

​​4、分析​​


一、ReadWriteLock读写锁

1、概述

官方文档介绍:

读可以多个线程读,写只能一个线程写;

【JUC】004-ReadWriteLock读写锁_多线程

 

2、问题引出

代码实现:

package com.zibo.rw;

import java.util.HashMap;
import java.util.Map;

//读写锁
public class TestReadWriteLock {
public static void main(String[] args) {
MyCache myCache = new MyCache();

//写入
for (int i = 0; i < 5; i++) {
final int finalI = i;
new Thread(()->{
myCache.put(finalI+"",finalI+"");
},String.valueOf(i)).start();
}

//读取
for (int i = 0; i < 5; i++) {
final int finalI = i;
new Thread(()->{
myCache.get(finalI+"");
},String.valueOf(i)).start();
}
}
}
//自定义缓存
class MyCache{
//volatile关键字:保证内存可见性
private volatile Map<String,Object> map = new HashMap<>();

//存,写
public void put(String key,Object value){
System.out.println(Thread.currentThread().getName() + "写入" + key);
map.put(key,value);
System.out.println(Thread.currentThread().getName() + "写入完毕!");
}

//取,读
public void get(String key){
System.out.println(Thread.currentThread().getName() + "读取" + key);
map.get(key);
System.out.println(Thread.currentThread().getName() + "读取完毕");
}
}

运行结果:

0写入0
4写入4
3写入3
3写入完毕!
1写入1
1写入完毕!
2写入2
4写入完毕!
0写入完毕!
2写入完毕!
0读取0
1读取1
0读取完毕
1读取完毕
2读取2
2读取完毕
3读取3
3读取完毕
4读取4
4读取完毕

问题:

出现了多线程不安全的问题,我们要实现的是“读可以多个线程读,写只能一个线程写”;

 

3、使用读写锁

代码实现:

package com.zibo.rw;

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

//读写锁

/*
* 分析:
* 独占锁(写锁):一次只能被一个线程占有;
* 共享锁(读锁):多个线程可以同时占有;
* 1、读-读:可以共存;
* 2、读-写:不可共存;
* 3、写-写:不可共存;
*/
public class TestReadWriteLock {
public static void main(String[] args) {
MyCacheLock myCache = new MyCacheLock();

//写入
for (int i = 0; i < 5; i++) {
final int finalI = i;
new Thread(()->{
myCache.put(finalI+"",finalI+"");
},String.valueOf(i)).start();
}

//读取
for (int i = 0; i < 5; i++) {
final int finalI = i;
new Thread(()->{
myCache.get(finalI+"");
},String.valueOf(i)).start();
}
}
}

//自定义缓存
class MyCacheLock{
//volatile关键字:保证内存可见性
private volatile Map<String,Object> map = new HashMap<>();
//更加细粒度的控制
private ReadWriteLock lock = new ReentrantReadWriteLock();


//存,写,写入的时候只希望同时只有一个线程进行
public void put(String key,Object value){
//加写锁
lock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "写入" + key);
map.put(key,value);
System.out.println(Thread.currentThread().getName() + "写入完毕!");
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放写锁
lock.writeLock().unlock();
}
}

//取,读
public void get(String key){
//加读锁
lock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "读取" + key);
map.get(key);
System.out.println(Thread.currentThread().getName() + "读取完毕");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.readLock().unlock();
}
}
}

//自定义缓存
class MyCache{
//volatile关键字:保证内存可见性
private volatile Map<String,Object> map = new HashMap<>();

//存,写
public void put(String key,Object value){
System.out.println(Thread.currentThread().getName() + "写入" + key);
map.put(key,value);
System.out.println(Thread.currentThread().getName() + "写入完毕!");
}

//取,读
public void get(String key){
System.out.println(Thread.currentThread().getName() + "读取" + key);
map.get(key);
System.out.println(Thread.currentThread().getName() + "读取完毕");
}
}

运行结果:

0写入0
0写入完毕!
1写入1
1写入完毕!
2写入2
2写入完毕!
3写入3
3写入完毕!
4写入4
4写入完毕!
0读取0
0读取完毕
4读取4
2读取2
2读取完毕
1读取1
1读取完毕
3读取3
3读取完毕
4读取完毕

 

4、分析

/*
* 分析:
* 独占锁(写锁):一次只能被一个线程占有;
* 共享锁(读锁):多个线程可以同时占有;
* 1、读-读:可以共存;
* 2、读-写:不可共存;
* 3、写-写:不可共存;
*/