簡體   English   中英

我是否必須將類擴展到 ConcurrentHashMap 或者我可以為 threadSafety 使用變量 ConcurrentHashMap

[英]Do I have to extend class to ConcurrentHashMap or can I have variable ConcurrentHashMap for threadSafety

我正在創建基於 Socket 的服務器-客戶端保留服務,並且有關於將被多個線程訪問的類的問題,是否需要擴展 ConcurrentHashMap 或者創建變量 ConcurrentHashMap 是否足以保證線程安全?

我有兩個想法,但我不確定第一個是否可行,所以第一個將創建僅實現 Serializable 的類,該類具有可變日期,然后是線程想要操作的變量 ConcurrentHashMap,第二個想法是擁有擴展 Concurrent 的類哈希映射,只是 CHP,但具有附加變量以確保它與其他變量區分開來

public class Day implements Serializable {
private LocalDate date;
private ConcurrentHashMap<String, Boolean> schedule;

public Day(LocalDate date){
    this.date = date;
    this.schedule = new ConcurrentHashMap<>();
    IntStream.range(10, 18).forEachOrdered(
            n -> this.schedule.put(LocalTime.of(n, 0).toString(), TRUE));
}

public void changeaval(String key,Boolean status) {
    this.schedule.replace(key,status);
}

public boolean aval(String key){
    return this.schedule.get(key);
}

public LocalDate getDate(){return this.date;}

public ConcurrentHashMap getSchedule(){return this.schedule;}

}

我只想擁有可以由多個線程訪問的類/對象,並且可以與其他線程/可比較的對象區分開來,並且具有映射 Int -> Boolean 的 ConcurrentHashMap 這是我第一次使用 Stack,這是我在 Java 中的第一個項目如果有什么不對的地方,我不知道很抱歉。

在處理多線程訪問的對象時,基本上有兩件事需要注意:

  1. 競爭條件 - 由於操作系統的線程調度和編譯器的指令重新排序優化,指令以程序員不希望的順序執行,導致錯誤
  2. 內存可見性 - 在多處理器系統中,一個處理器所做的更改並不總是立即對其他處理器可見。 出於性能原因,處理器將內容保存在其本地寄存器和緩存中,因此對其他處理器正在執行的線程不可見。

幸運的是,我們可以使用適當的同步來處理這兩種情況。

讓我們來談談這個特定的程序。

Localdate本身是一個不可變的線程安全類。 如果我們查看這個類的源代碼,我們會看到這個類的所有字段都是final 這意味着只要Localdate的構造Localdate完成對象的初始化,對象本身就會跨線程可見。 但是當它被賦值給不同對象中的引用變量時,這個賦值(即引用變量的內容)是否對其他線程可見是我們需要注意的。

鑒於您的情況下的構造函數,我們可以確保字段date跨線程的可見性提供的datefinalvolatile 由於您沒有修改類中的date字段,因此您可以很好地將其設為 final,從而確保安全初始化。 如果您稍后決定為此字段使用 setter 方法(取決於您的業務邏輯和您的設計),您應該將該字段設置為volatile而不是final volatile創建了一個發生在之前的關系,這意味着在寫入volatile變量之前在特定線程中執行的任何指令將立即對其他線程可見,一旦它們讀取相同的 volatile 變量。

ConcurrentHashMap 您應該使現場schedule final 由於ConcurrentHashMap本身具有所有必要的同步,因此當其他線程嘗試讀取它時,您針對鍵設置的任何值都將可見。

但是請注意,如果您有一些可變對象作為ConcurrentHashMap值而不是Boolean ,則必須以與上述相同的方式設計它。

此外,知道有一個叫做piggy-backing的概念可能會很好,這意味着如果一個線程寫入其所有字段然后寫入volatile變量,則該線程在寫入volatile變量之前寫入的所有內容都是可見的給其他線程,前提是其他線程在第一個線程寫入后首先讀取volatile變量的值。 但是當你這樣做時,你必須非常仔細地確保讀取和寫入的順序,而且很容易出錯。 因此,當您想從一段罕見的代碼中擠出最后一滴性能時,就會這樣做。 在性能之前優先考慮安全性、可維護性、可讀性。

最后,代碼中沒有競爭條件。 發生的唯一寫入是在ConcurrentHashMap ,它本身是線程安全的。

基本上,這兩種方法是等效的。 從架構的角度來看,在專用類中創建變量是首選,因為可以更好地控制用戶可以訪問哪些方法。 在擴展時,用戶可以訪問底層 ConcurrentHashMap 的許多方法並濫用它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM