![](/img/trans.png)
[英]How Can I remove an item from ConcurrentHashMap when no have a thread holding certain object anymore?
[英]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 中的第一個項目如果有什么不對的地方,我不知道很抱歉。
在處理多線程訪問的對象時,基本上有兩件事需要注意:
幸運的是,我們可以使用適當的同步來處理這兩種情況。
讓我們來談談這個特定的程序。
Localdate
本身是一個不可變的線程安全類。 如果我們查看這個類的源代碼,我們會看到這個類的所有字段都是final
。 這意味着只要Localdate
的構造Localdate
完成對象的初始化,對象本身就會跨線程可見。 但是當它被賦值給不同對象中的引用變量時,這個賦值(即引用變量的內容)是否對其他線程可見是我們需要注意的。
鑒於您的情況下的構造函數,我們可以確保字段date
跨線程的可見性提供的date
是final
或volatile
。 由於您沒有修改類中的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.