1_基礎(chǔ)知識_chapter05_基礎(chǔ)構(gòu)建模塊_1_同步容器類

  • 委托是創(chuàng)建線程安全類的一個最有效的策略, 只需讓現(xiàn)有的線程安全類管理所有的狀態(tài)即可

  • Collections.synchronizedXXX是一些同步容器類, 這些類的實(shí)現(xiàn)方式是將它們的狀態(tài)封裝起來, 并且對每個公有方法都進(jìn)行同步

  • 同步容器類包括 Vector, HashTable, Collections.synchronizedXXX

  • 同步容器類的問題

    (1) 同步容器類是線程安全的, 但是在執(zhí)行復(fù)合操作時仍需要客戶端加鎖

    復(fù)合操作有:

    迭代

    跳轉(zhuǎn)(根據(jù)指定順序找到當(dāng)前元素的下一個元素)

    條件運(yùn)算(若容器中不存在某個元素, 則添加這個元素)

示例

    public class SafeVectorHelpers {
    
        public static Object getLast(Vector list) {
    
            int lastIndex = list.size() - 1;
            return list.get(lastIndex);
        }

        public static void deleteLast(Vector list) {
    
            int lastIndex = list.size() - 1;
            list.remove(lastIndex);
        }
    }

當(dāng)有兩個線程分別對同一個Vector容器執(zhí)行g(shù)etLast和deleteLast函數(shù)時, 一個執(zhí)行完get(),另一個執(zhí)行remove就會報錯

(2) 為了保證復(fù)合操作的線程安全性就要加鎖, 此時符合"客戶端加鎖"的條件:找到同步容器使用了哪一個鎖,并對它加鎖
  • 迭代器的迭代問題

    (1) 無論顯式用迭代器迭代還是用for-each語法, 本質(zhì)都是使用Iterator迭代

    (2) 容器使用了及時失敗機(jī)制: 當(dāng)發(fā)現(xiàn)容器在迭代過程中被外部更改或其他線程更改時, 報ConcurrentModification異常

    (3) 防止容器報ConcurrentModification異常的手段

    加鎖

    先克隆容器, 再在克隆容器上迭代(克隆過程也要加鎖)

    兩種手段都會使性能下降, 綜合考慮各種因素才能比較出兩種手段在不同場合下的優(yōu)劣

    (3) 隱藏迭代器

    很多時候方法內(nèi)部也使用了迭代, 但是隱藏了起來, 這時不注意的話就有多線程迭代異常的問題

    示例

      public class HiddenIterator {
    
          @GuardedBy("this")
          private final Set<Integer> set = new HashSet<Integer>();
    
          public synchronized void add(Integer i) {
              set.add(i);
          }
    
          public synchronized void remove(Integer i) {
              set.remove(i);
          }
    
          public void addTenThings() {
    
              Random r = new Random();
    
              for (int i = 0; i < 10; i++) {
                  this.add(r.nextInt());
              }
    
              System.out.println(this.set);
          }
      }
    

    這里的addTenThings函數(shù)的最后一行System.out.println(this.set)會隱式調(diào)用set的迭代器, 將set中的所有元素轉(zhuǎn)換為String, 如果此時其他線程調(diào)用了add或remove函數(shù), 就會出現(xiàn)迭代異常

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、基礎(chǔ)知識:1、JVM、JRE和JDK的區(qū)別:JVM(Java Virtual Machine):java虛擬機(jī)...
    殺小賊閱讀 2,560評論 0 4
  • 進(jìn)程和線程 進(jìn)程 所有運(yùn)行中的任務(wù)通常對應(yīng)一個進(jìn)程,當(dāng)一個程序進(jìn)入內(nèi)存運(yùn)行時,即變成一個進(jìn)程.進(jìn)程是處于運(yùn)行過程中...
    勝浩_ae28閱讀 5,257評論 0 23
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍(lán)閱讀 42,790評論 11 349
  • Java8張圖 11、字符串不變性 12、equals()方法、hashCode()方法的區(qū)別 13、...
    Miley_MOJIE閱讀 3,895評論 0 11
  • 說到撒謊,小朋友都知道,撒謊是不對的。但是,我這次撒謊卻包含著對媽媽的濃濃的愛。 ...
    是瀅瀅呀閱讀 299評論 0 3

友情鏈接更多精彩內(nèi)容