目录
一、ReadWriteLock读写锁
1、概述
官方文档介绍:
2、问题引出
代码实现:
运行结果:
问题:
3、使用读写锁
代码实现:
运行结果:
4、分析
一、ReadWriteLock读写锁
1、概述
官方文档介绍:
读可以多个线程读,写只能一个线程写;
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、写-写:不可共存;
*/