读写锁(ReentrantReadWriteLock)
概念
-
独占锁:指该锁一次只能被一个线程所持有,对ReentrantLock和Synchronized而言都是独占锁
-
共享锁:只该锁可被多个线程所持有
ReentrantReadWriteLock:其读锁是共享锁,写锁是独占锁
-
互斥锁:读锁的共享锁可以保证并发读是非常高效的,读写、写读、写写的过程是互斥的
例子:
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* @autuor caipc
* @date 2020/12/7 21:24
**/
class MyCache{
private volatile Map<String,Object> map =new HashMap<>();
private ReentrantReadWriteLock rReadWriteLock =new ReentrantReadWriteLock();
public void put(String key,Object value){
rReadWriteLock.writeLock().lock();
try {
System.out.println("线程"+Thread.currentThread().getName()+"开始写入"+key);
try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace();}
map.put(key,value);
System.out.println("线程"+Thread.currentThread().getName()+"写入完成");
} finally {
rReadWriteLock.writeLock().unlock();
}
}
public void get(String key){
rReadWriteLock.readLock().lock();
try {
System.out.println("线程"+Thread.currentThread().getName()+"开始读");
Object result = map.get(key);
System.out.println("线程"+Thread.currentThread().getName()+"读"+result+"完成");
} finally {
rReadWriteLock.readLock().unlock();
}
}
}
public class ReadWriteLockDemo {
public static void main(String[] args) {
MyCache myCache =new MyCache();
for (int i = 0; i <5 ; i++) {
final int temp=i;
new Thread(()->{
myCache.put(temp+"",temp);
},String.valueOf(i)).start();
}
for (int i = 0; i <5 ; i++) {
final int temp=i;
new Thread(()->{
myCache.get(temp+"");
},String.valueOf(i)).start();
}
}
}
读写锁的特征:
- 允许多个线程同时读共享变量;
- 只允许一个线程写共享变量;
- 如果有一个线程在执行写操作,那么禁止读操作。