读锁(共享锁)写锁(独占锁)解析
程序员文章站
2022-11-30 14:30:01
读锁(共享锁)写锁(独占锁)解析在多线程环境下一个资源类被读是没有任何问题的,所以满足并发要求,但是,如果有一个线程去写共享资源,那么就不应该再有其他线程可以对该资源进行读或写了。也就是说,读-读可以共存,读-写不能共存,写-写不能共存。举例说明:首先我们手写一个缓存类,不加锁看执行结果package com.example.demo;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import...
读锁(共享锁)写锁(独占锁)解析
在多线程环境下一个资源类被读是没有任何问题的,所以满足并发要求,但是,如果有一个线程去写共享资源,那么就不应该再有其他线程可以对该资源进行读或写了。也就是说,读-读可以共存,读-写不能共存,写-写不能共存。
举例说明:
首先我们手写一个缓存类,不加锁看执行结果
package com.example.demo;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.TimeUnit;
class MyCache{
private volatile Map<String,Object> map=new HashMap<>();
public void put(String key,Object value){
System.out.println(Thread.currentThread().getName()+"\t正在写入:"+value);
//模拟网络通信延迟
try {
TimeUnit.MILLISECONDS.sleep(500);
}catch (Exception e){
e.printStackTrace();
}
map.put(key,value);
System.out.println(Thread.currentThread().getName()+"\t正在写成:");
}
public void get(String key){
System.out.println(Thread.currentThread().getName()+"\t正在读取:");
//模拟网络通信延迟
try {
TimeUnit.MILLISECONDS.sleep(500);
}catch (Exception e){
e.printStackTrace();
}
Object result=map.get(key);
System.out.println(Thread.currentThread().getName()+"\t读取完成:"+result);
}
}
/**
* Created by Administrator on 2020/7/5.
* 读写锁讲解
* 1.读锁(共享锁)
* 2.写锁(独占锁)
* @author qtx
*/
public class ReadAndWriteLockDemo {
public static void main(String[] args) {
MyCache myCache=new MyCache();
//5个线程写
for (int i = 0; i < 5; i++) {
final int temp=i;
new Thread(() -> {
myCache.put(temp+"",temp+"");
}).start();
}
//5个线程读
for (int i = 0; i < 5; i++) {
final int temp=i;
new Thread(() -> {
myCache.get(temp+"");
}).start();
}
}
}
可以看出,写没有完成,就被读取操作进行加塞
加塞读写锁之后效果
package com.example.demo;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;
class MyCache {
private volatile Map<String, Object> map = new HashMap<>();
private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
public void put(String key, Object value) {
//加入读锁
rwLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "\t正在写入:" + value);
//模拟网络通信延迟
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
map.put(key, value);
System.out.println(Thread.currentThread().getName() + "\t写入完成:");
} catch (Exception e) {
e.printStackTrace();
} finally {
rwLock.writeLock().unlock();
}
}
public void get(String key) {
//加入写锁
rwLock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName() + "\t正在读取:");
//模拟网络通信延迟
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
Object result = map.get(key);
System.out.println(Thread.currentThread().getName() + "\t读取完成:" + result);
} catch (Exception e) {
e.printStackTrace();
} finally {
rwLock.readLock().unlock();
}
}
}
/**
* Created by Administrator on 2020/7/5.
* 读写锁讲解
* 1.读锁(共享锁)
* 2.写锁(独占锁)
*
* @author qtx
*/
public class ReadAndWriteLockDemo {
public static void main(String[] args) {
MyCache myCache = new MyCache();
//5个线程写
for (int i = 0; i < 5; i++) {
final int temp = i;
new Thread(() -> {
myCache.put(temp + "", temp + "");
}).start();
}
//5个线程读
for (int i = 0; i < 5; i++) {
final int temp = i;
new Thread(() -> {
myCache.get(temp + "");
}).start();
}
}
}
运行结果满足要求,只有先全部写完,才能进行读取
本文地址:https://blog.csdn.net/u014385267/article/details/107145045
下一篇: SpringBoot实战教程-知识点拾遗
推荐阅读
-
使用wifi共享精灵的过程中电脑会自动休眠锁屏的解决方法
-
解析oracle对select加锁的方法以及锁的查询
-
MySQL锁(表锁,行锁,共享锁,排它锁,间隙锁)使用详解
-
读锁(共享锁)写锁(独占锁)解析
-
死磕 java同步系列之ReentrantLock源码解析(二)——条件锁
-
死磕 java同步系列之ReentrantLock源码解析(一)——公平锁、非公平锁
-
python使用锁访问共享变量实例解析
-
可重入不可重入锁,自旋锁,独占锁(写锁),共享锁(读锁),互斥锁,学习案例
-
mysql repeatable-read 一次利用间隙锁解决幻读案例
-
mysql repeatable-read 一次利用间隙锁解决幻读案例