亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺析Java如何在并發(fā)環(huán)境下生成一個只讀的map

 更新時間:2024年04月18日 08:39:42   作者:Layber  
這篇文章主要為大家詳細介紹了Java如何在并發(fā)環(huán)境下生成一個只讀的map,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

前言

在日常開發(fā)過程中,我們經(jīng)常會遇到一些資源初始化的情況,往往有些資源就是那種我初始化以后我們就不希望被改動,但是我們又擔心別人使用的時候不小心改動了,這時候我就在想,要是我們的JDK能提供一種不能被修改的容器改有多好,好死不死,jdk中還真有這樣的容器,map和list都有,這里以map為例子給大家講解一下!

一般用法

在項目中一些不被改變的資源,通常采用靜態(tài)代碼塊的形式去初始化,如下:

  private static Map<Integer, String> readOnlyMap;

  static {
        Map<Integer, String> callTimesMap = new HashMap<>();
        callTimesMap.put(1, "一呼");
        callTimesMap.put(2, "二呼");
        callTimesMap.put(3, "三呼");
        callTimesMap.put(4, "四呼");
        callTimesMap.put(5, "五呼");
        callTimesMap.put(6, "六呼");
        callTimesMap.put(7, "七呼");
        callTimesMap.put(8, "八呼");
        callTimesMap.put(9, "九呼");
        callTimesMap.put(10, "十呼");

        readOnlyMap = Collections.unmodifiableMap(callTimesMap);
    }

練習時長兩年半左右的Java練習生應該知道,這樣做的好處是由靜態(tài)代碼塊在Java虛擬機中的執(zhí)行時機所決定的,下面給大伙呱唧一下!

靜態(tài)代碼塊在Java中如何執(zhí)行

在Java中,靜態(tài)代碼塊由類加載器在加載類的過程中執(zhí)行。當類被第一次加載時,類加載器會執(zhí)行其中的靜態(tài)代碼塊,并且只會執(zhí)行一次。

創(chuàng)建只讀的容器

要創(chuàng)建只讀的容器其實也很簡單:

Collections.unmodifiableMap(callTimesMap);

這樣就可以實現(xiàn)了!

測試證明

      public static void main(String[] args) {
       //模擬并發(fā)環(huán)境
        new Thread(()->{
            readOnlyMap.put(11,"s");
        }).start();
        
         readOnlyMap.put(11,"s");
    }

測試結(jié)果:

Exception in thread "Thread-0" java.lang.UnsupportedOperationException
    at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
    at com.zhuiyi.yicall.callout.statistic.impl.SessionStatisticServiceImpl.lambda$main$0(SessionStatisticServiceImpl.java:94)
    at java.lang.Thread.run(Thread.java:748)
    
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.util.Collections$UnmodifiableMap.put(Collections.java:1459)
    at com.zhuiyi.yicall.callout.statistic.impl.SessionStatisticServiceImpl.main(SessionStatisticServiceImpl.java:96)

我們可以看到“Thread-0”和"main"線程都拋出了異常!這說明在并發(fā)條件下確實不允許寫,只允許讀!

只讀容器的底層實現(xiàn)原理

直接上源碼:

      private static class UnmodifiableMap<K,V> implements Map<K,V>, Serializable {
        private static final long serialVersionUID = -1034234728574286014L;

        private final Map<? extends K, ? extends V> m;

        UnmodifiableMap(Map<? extends K, ? extends V> m) {
            if (m==null)
                throw new NullPointerException();
            this.m = m;
        }

        public int size()                        {return m.size();}
        public boolean isEmpty()                 {return m.isEmpty();}
        public boolean containsKey(Object key)   {return m.containsKey(key);}
        public boolean containsValue(Object val) {return m.containsValue(val);}
        public V get(Object key)                 {return m.get(key);}

        public V put(K key, V value) {
            throw new UnsupportedOperationException();
        }
        public V remove(Object key) {
            throw new UnsupportedOperationException();
        }
        public void putAll(Map<? extends K, ? extends V> m) {
            throw new UnsupportedOperationException();
        }
        public void clear() {
            throw new UnsupportedOperationException();
        }
        //.....此處省略很多代碼
      }

從源碼中我們可以看出,UnmodifiableMap實現(xiàn)了map接口,所以它具有map的所有功能,同時最最重要的是他將所有會動到容器中的數(shù)據(jù)的方法都拋出異常了!

如下:

        public V put(K key, V value) {
            throw new UnsupportedOperationException();
        }
        public V remove(Object key) {
            throw new UnsupportedOperationException();
        }
        public void putAll(Map<? extends K, ? extends V> m) {
            throw new UnsupportedOperationException();
        }
        public void clear() {
            throw new UnsupportedOperationException();
        }

這樣就從源頭上控制了容器不支持寫,只支持讀!

思考:針對這樣的場景,是否還有別的實現(xiàn)方式?

答案肯定是有的,我們可以使用一個全局鎖,或者分布式鎖都能實現(xiàn)!

全局讀鎖:

    ReadWriteLock lock = new ReentrantReadWriteLock();
    
    public void readData() {
        lock.readLock().lock();
        try {
            // 執(zhí)行讀取操作callTimesMap
            
        } finally {
            lock.readLock().unlock();
        }
    }

如果使用分布式鎖或者全局鎖的話性能會變差,所以最好的解決方案就是直接創(chuàng)建一個不能被修改的容器,這樣效率是最高,也是最安全的!

到此這篇關(guān)于淺析Java如何在并發(fā)環(huán)境下生成一個只讀的map的文章就介紹到這了,更多相關(guān)Java并發(fā)生成只讀map內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot使用minio及配置代碼

    SpringBoot使用minio及配置代碼

    MinIO是一個非常輕量的服務(wù),可以很簡單的和其他應用的結(jié)合,類似?NodeJS,?Redis?或者?MySQL。本文重點給大家介紹SpringBoot使用minio及配置代碼,感興趣的朋友一起看看吧
    2022-02-02
  • SpringBoot如何使用過濾器進行XSS防御

    SpringBoot如何使用過濾器進行XSS防御

    想對全局的請求都進行XSS防御可以使用servlet中的過濾器或者spring mvc中的攔截器,下面我們就來看看如何使用servlet中的過濾器進行XSS防御吧
    2024-11-11
  • SpringBoot+netty-socketio實現(xiàn)服務(wù)器端消息推送

    SpringBoot+netty-socketio實現(xiàn)服務(wù)器端消息推送

    這篇文章主要介紹了SpringBoot+netty-socketio實現(xiàn)服務(wù)器端消息推送,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • Java實現(xiàn)將PDF轉(zhuǎn)為PDF/A

    Java實現(xiàn)將PDF轉(zhuǎn)為PDF/A

    通過將PDF格式轉(zhuǎn)換為PDF/A格式,可保護文檔布局、格式、字體、大小等不受更改,從而實現(xiàn)文檔安全保護的目的,同時又能保證文檔可讀、可訪問。本文將為大家介紹如何實現(xiàn)這一轉(zhuǎn)換,需要的可以參考一下
    2022-01-01
  • Java自動釋放鎖的三種實現(xiàn)方案

    Java自動釋放鎖的三種實現(xiàn)方案

    在筆者面試過程時,經(jīng)常會被問到各種各樣的鎖,如樂觀鎖、讀寫鎖等等,非常繁多,下面這篇文章主要給大家介紹了關(guān)于Java自動釋放鎖的三種實現(xiàn)方案,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • 詳解Java設(shè)計模式編程中的Flyweight享元模式的開發(fā)結(jié)構(gòu)

    詳解Java設(shè)計模式編程中的Flyweight享元模式的開發(fā)結(jié)構(gòu)

    這篇文章主要介紹了Java設(shè)計模式編程中的Flyweight享元模式的開發(fā)結(jié)構(gòu),享元模式能夠最大限度地重用現(xiàn)有的同類對象,需要的朋友可以參考下
    2016-04-04
  • 淺談synchronized方法對非synchronized方法的影響

    淺談synchronized方法對非synchronized方法的影響

    下面小編就為大家?guī)硪黄獪\談synchronized方法對非synchronized方法的影響。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • java控制臺實現(xiàn)學生信息管理系統(tǒng)(IO版)

    java控制臺實現(xiàn)學生信息管理系統(tǒng)(IO版)

    這篇文章主要為大家詳細介紹了java控制臺實現(xiàn)學生信息管理系統(tǒng)(IO版),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • 自定義mybatis插件如何實現(xiàn)sql日志打印

    自定義mybatis插件如何實現(xiàn)sql日志打印

    這篇文章主要介紹了自定義mybatis插件如何實現(xiàn)sql日志打印問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • Java微信授權(quán)登陸的實現(xiàn)示例

    Java微信授權(quán)登陸的實現(xiàn)示例

    微信授權(quán)登錄,官方文檔寫的比較簡潔。所以對于會的人一目了然,而對于新手剛?cè)腴T的人來說是舉步維艱。本文詳細的介紹了Java微信授權(quán)登陸的實現(xiàn)示例,感興趣的朋友可以了解一下
    2021-06-06

最新評論