1. 程式人生 > 其它 >4.讀寫鎖(ReadWriteLock)

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