1. 程式人生 > >如何在匿名thread子類中保證執行緒安全

如何在匿名thread子類中保證執行緒安全

在做效能測試的過程中,我寫了兩個虛擬類ThreadLimitTimeCountThreadLimitTimesCount做框架,通過對執行緒的標記來完成超時請求的記錄。舊方法如下:

 @Override
    protected void after() {
        requestMark.addAll(marks);
        marks = new ArrayList<>();
        GCThread.stop();
        synchronized (this.getClass()) {
            if (countDownLatch.getCount() == 0 && requestMark.size() != 0) {
                Save.saveStringList(requestMark, MARK_Path.replace(LONG_Path, EMPTY) + Time.getDate().replace(SPACE_1, CONNECTOR));
                requestMark = new Vector<>();
            }
        }
    }

其中我用了synchronized關鍵字同步,但是在匿名類的單元測試中出現一個BUG,匿名類中沒有實現clone()方法,也不能直接使用深拷貝方法,導致無法直接複製物件,所以我建立了多個功能相同的匿名執行緒類。問題來了,在程式碼執行過程中,偶然會出現記錄markrequest的文件中出現空內容的形式。

我查詢了一些資料,感覺問題出現在synchronized (this.getClass())這個問題了,因為我列印this.getClass()給我的是當前測試類的類名,感覺原因就是匿名類的問題,匿名類相當於多個實現類,synchronized (this.getClass())無法保證多各類物件同時訪問這個方法的執行緒安全。最終,我選擇了另外一種方式,就是單獨寫一個執行緒安全的save()

方法,這樣就可以保證所有訪問儲存方法的執行緒的安全,將清空記錄列表的功能也放在了這個執行緒安全的方法裡了。

    /**
     * 同步save資料,用於匿名類多執行緒儲存測試資料
     *
     * @param data
     * @param name
     */
    public static void saveStringListSync(Collection<String> data, String name) {
        synchronized (Save.class) {
            if (data.isEmpty()) return;
            saveStringList(data, name);
        }
    }

原來虛擬類的方法就變成了如下的樣子:

            if (countDownLatch.getCount() == 0 && requestMark.size() != 0) {
                Save.saveStringListSync(requestMark, MARK_Path.replace(LONG_Path, EMPTY) + Time.getDate().replace(SPACE_1, CONNECTOR));
            }

  • 鄭重宣告:文章首發於公眾號“FunTester”,禁止第三方(騰訊雲除外)轉載、發表。

技術類文章精選

  • java一行程式碼列印心形
  • Linux效能監控軟體netdata中文漢化版
  • 效能測試框架第二版
  • 如何在Linux命令列介面愉快進行效能測試
  • 圖解HTTP腦圖
  • 將swagger文件自動變成測試程式碼
  • 基於java的直線型介面測試框架初探
  • Selenium 4.0 Alpha更新日誌
  • Selenium 4.0 Alpha更新實踐
  • 如何統一介面測試的功能、自動化和效能測試用例

非技術文章精選

  • 為什麼選擇軟體測試作為職業道路?
  • 寫給所有人的程式設計思維
  • 成為自動化測試的7種技能
  • 如何在DevOps引入自動化測試
  • Web端自動化測試失敗原因彙總
  • 如何在DevOps引入自動化測試
  • 測試人員常用藉口
  • API測試基礎
  • API自動化測試指南
  • 未來的QA測試工程師