读写锁ReadWriteLock
lock锁,只允许一个进程进行读/写
使用ReadWriteLock读写锁,可以实现控制:
多个线程同时读
同一时间只允许一个线程写
下面的demo展示的是,当多个线程要进行同时写操作时,没有加锁的情况,会导致多个线程并发写:
运行结果:
代码:
/**
* @author zkw
* @Description 读写锁
*/
public class ReadWriteLockDemo {
public static void main(String[] args) {
MyMap map = new MyMap();
for (int i = 0; i < 6; i++) {
new Thread(()->{
try {
map.put(Thread.currentThread().getName(),"");
} catch (InterruptedException e) {
e.printStackTrace();
}
},i+"").start();
}
for (int i = 0; i < 6; i++) {
new Thread(()->{
try {
map.get(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
},i+"").start();
}
}
}
class MyMap{
private HashMap<String,String> map = new HashMap<>();
public void put(String key,String value) throws InterruptedException {
System.out.println(Thread.currentThread().getName()+"开始写入");
TimeUnit.SECONDS.sleep(1);
map.put(key, value);
System.out.println(Thread.currentThread().getName()+"写入完成");
}
public String get(String key) throws InterruptedException {
System.out.println(Thread.currentThread().getName()+"开始读取");
TimeUnit.SECONDS.sleep(1);
String s = map.get(key);
System.out.println(Thread.currentThread().getName()+"读取完成");
return s;
}
}
下面使用ReadWriteLock锁对上面的demo进行优化,禁止多个线程同时读的情况,并允许多个线程同时写:
运行结果:
代码:
/**
* @author zkw
* @Description 读写锁
*/
public class ReadWriteLockDemo {
public static void main(String[] args) {
MyMap map = new MyMap();
for (int i = 0; i < 6; i++) {
new Thread(()->{
try {
map.put(Thread.currentThread().getName(),"");
} catch (InterruptedException e) {
e.printStackTrace();
}
},i+"").start();
}
for (int i = 0; i < 6; i++) {
new Thread(()->{
try {
map.get(Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
},i+"").start();
}
}
}
class MyMap{
private HashMap<String,String> map = new HashMap<>();
ReadWriteLock readWriteLock = new ReentrantReadWriteLock(); //创建读写锁
public void put(String key,String value) throws InterruptedException {
readWriteLock.writeLock().lock(); //写锁
System.out.println(Thread.currentThread().getName()+"开始写入");
TimeUnit.SECONDS.sleep(1);
map.put(key, value);
System.out.println(Thread.currentThread().getName()+"写入完成");
readWriteLock.writeLock().unlock();
}
public String get(String key) throws InterruptedException {
readWriteLock.readLock().lock(); //读锁
System.out.println(Thread.currentThread().getName()+"开始读取");
TimeUnit.SECONDS.sleep(1);
String s = map.get(key);
System.out.println(Thread.currentThread().getName()+"读取完成");
readWriteLock.readLock().unlock();
return s;
}
}