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();

 

posted @ 2022-05-13 21:06  努力的达子  阅读(242)  评论(0编辑  收藏  举报