4.读写锁(ReadWriteLock)
读写锁:操作一个资源,写只能一个线程,读可以多个线程
具体代码如下:
public class ReadWriteLock_Demo {
public static void main(String[] args) {
//创建了六个读线程和六个写线程去操作缓存!
Mycache mycache=new Mycache();
for (int i = 1; i < 6; i++) {
final int temp=i;
new Thread(()->{
mycache.put(""+temp , temp);
},"放->"+i).start();
}
for (int i = 1; i < 6; i++) {
final int temp=i;
new Thread(()->{
mycache.get(temp+"");
},"取->"+i).start();
}
}
}
class Mycache{
private volatile Map<String,Object> map=new HashMap<>();
//存写
public void put(String key,Object value){
System.out.println(Thread.currentThread().getName()+":写入..."+key+"="+value);
map.put(key, value);
System.out.println(Thread.currentThread().getName()+"写入完成!");
}
public void get(String key) {
System.out.println(Thread.currentThread().getName()+":获取.."+key);
Object value=map.get(key);
System.out.println(Thread.currentThread().getName()+"获取完成!");
}
}
运行结果如下:
放->1:写入...1=1
放->2:写入...2=2
放->1写入完成!
放->2写入完成!
。。。
发现写操作,一个还没执行完毕时,另外一个线程就开始操作,写操作只能一个线程进行!
改进:
class Mycache{
private volatile Map<String,Object> map=new HashMap<>();
//重点1:加入读写锁ReadWriteLock/ReentrantReadWriteLock
ReadWriteLock readWriteLock=new ReentrantReadWriteLock();
//存写
public void put(String key,Object value){
//重点2:写锁上锁,写操作只能一个线程进行,所以也称之为(独占锁)
readWriteLock.writeLock().lock();
try {
System.out.println(Thread.currentThread().getName()+":写入..."+key+"="+value);
map.put(key, value);
System.out.println(Thread.currentThread().getName()+"写入完成!");
} catch (Exception e) {
e.printStackTrace();
} finally {
//重点3:写锁解锁
readWriteLock.writeLock().unlock();
}
}
public void get(String key) {
//重点4:读锁上锁,该锁作用支持多线程共享资源。所以又称为(共享锁)
readWriteLock.readLock().lock();
try {
System.out.println(Thread.currentThread().getName()+":获取.."+key);
Object value=map.get(key);
System.out.println(Thread.currentThread().getName()+"获取完成!");
} catch (Exception e) {
e.printStackTrace();
} finally {
readWriteLock.readLock().unlock();
}
}
}
此时输出:
放->1:写入...1=1
放->1写入完成!
放->2:写入...2=2
放->2写入完成!
放->3:写入...3=3
放->3写入完成!
放->4:写入...4=4
放->4写入完成!
放->5:写入...5=5
放->5写入完成!
取->1:获取..1
取->1获取完成!
取->3:获取..3
取->2:获取..2
取->2获取完成!
取->3获取完成!
取->4:获取..4
取->4获取完成!
取->5:获取..5
取->5获取完成!
发现:
1.写操作:
只能一个线程操作,一个线程写完后,另外一个线程执行
2.读操作
可以多个线程共享资源
结论:
1.写锁,一次只能被一个线程占用。所以又称之为独占锁
readWriteLock.writeLock().lock();
2.读锁:多个线程可以同时占有,所以也可以称为共享锁
readWriteLock.readLock().lock();