读写锁
- 独占锁(写锁)
- 共享锁(读锁)
public class ReadWriteLockTest {
public static void main(String[] args) {
MyCache myCache = new MyCache();
for (int i = 1; i <= 5; i++) {
final String temp = i + "";
new Thread(()->{
myCache.put(temp,temp);
},String.valueOf(i)).start();
}
for (int i = 1; i <= 5; i++) {
final String temp = i + "";
new Thread(()->{
myCache.get(temp);
},String.valueOf(i)).start();
}
}
}
class MyCache {
private volatile Map<String,String> map = new HashMap<>();
public void put(String key, String value) {
System.out.println(Thread.currentThread().getName()+"写入");
map.put(key,value);
System.out.println(Thread.currentThread().getName()+"写入完毕");
}
public void get(String key) {
System.out.println(Thread.currentThread().getName()+"获取");
String s = map.get(key);
System.out.println(Thread.currentThread().getName()+"获取完毕");
}
}
- 存在的问题:写入会交叉
- 加入读写锁
class MyCacheLock {
private volatile Map<String,String> map = new HashMap<>();
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
public void put(String key, String value) {
readWriteLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"写入");
map.put(key,value);
System.out.println(Thread.currentThread().getName()+"写入完毕");
} catch (Exception e) {
e.printStackTrace();
} finally {
readWriteLock.writeLock().unlock();
}
}
public void get(String key) {
readWriteLock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()+"获取");
String s = map.get(key);
System.out.println(Thread.currentThread().getName()+"获取完毕");
} catch (Exception e) {
e.printStackTrace();
} finally {
readWriteLock.readLock().unlock();
}
}
}
- 执行结果: 写入无插队现象
总结 - 写-写互斥
- 读-写互斥
- 读-读不互斥
让读写锁比普通锁有更高的并发性。是lock能取代synchronized的原因之一 - 独占锁(写锁):一次只能被一个线程占有
- 共享锁(读锁):多个线程可以同时占用