如何在匿名thread子類中保證線程安全

在作性能測試的過程當中,我寫了兩個虛擬類ThreadLimitTimeCountThreadLimitTimesCount作框架,經過對線程的標記來完成超時請求的記錄。舊方法以下:java

@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」,禁止第三方(騰訊雲除外)轉載、發表。

技術類文章精選

非技術文章精選

相關文章
相關標籤/搜索