版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/havebeenstand/article/details/83616162
读写锁
读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,写锁和写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可。如果你的代码只读数据,可以很多人同时读,但是不能同时写,那就让读锁;如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁。总之,读的时候上读锁,写的时候上写锁!
读写锁的应用:
假设开启三个线程写数据,三个线程读数据(读读不互斥,读写互斥,写写互斥)
public class ReadWriteLockStudy {
public static void main(String[] args) {
ReadAndWrite raw = new ReadAndWrite();
for(int i = 0;i < 3;i++){
new Thread(new Runnable() {
@Override
public void run() {
raw.get();//读
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
raw.set(Math.random()*1000);//写
}
}).start();
}
}
}
class ReadAndWrite{
private Object data = null;
ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public void get(){
readWriteLock.readLock().lock();;
System.out.println(Thread.currentThread().getName()+" be ready to read");
try {
Thread.sleep((long)Math.random()*1000);
System.out.println(Thread.currentThread().getName()+" has read data:"+data);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
readWriteLock.readLock().unlock();
}
}
public void set(Object data){
readWriteLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName()+" be ready to write");
Thread.sleep((long)Math.random()*1000);
this.data = data;
System.out.println(Thread.currentThread().getName()+" has write data:"+this.data);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
readWriteLock.writeLock().unlock();
}
}
}
面试题:写一个缓存系统的伪代码
public class CacheDemoStudy {
private Map<String,Object> cache = new HashMap<String,Object>();
public static void main(String[] args) {
final CacheDemoStudy cacheDemoStudy = new CacheDemoStudy();
for(int i = 0;i < 5;i++){
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"拿到数据"+cacheDemoStudy.getData("dataKey"));
}
}).start();
}
}
private ReadWriteLock rwl = new ReentrantReadWriteLock();
public Object getData(String key){
rwl.readLock().lock();
try{
System.out.println(Thread.currentThread().getName()+"去拿数据");
if(cache.get(key) == null){
System.out.println(Thread.currentThread().getName()+"没有拿到数据");
}
if(cache.get(key) == null){
rwl.readLock().unlock();
rwl.writeLock().lock();
try{
if(cache.get(key) == null){
System.out.println(Thread.currentThread().getName()+"去写数据");
cache.put("dataKey", "aaaaa");
}
}finally{
rwl.writeLock().unlock();
}
rwl.readLock().lock();
}
}finally {
rwl.readLock().unlock();
}
return cache.get(key);
}
}
执行结果:
只去写了一次数据