很久以前我很頭疼,希望有一些幫助。
我想存儲很多Task
與ConcurrentSkipListMap
其中內部是ConcurrentHashMap
稱爲多段鎖。
這個簡單的例子代碼顯示使用Scala(Java也可讀):
val tasks = new ConcurrentSkipListMap[TaskKey, Task]()
參閱類簡單:如何鎖定free在java/scala中使用兩個ConcurrentHashMap?
class TaskKey(id: String, systemTime: Long)
用於身份任務 TaskKey類是唯一的,並且任務如下:
trait Task {
val taskId: TaskKey //account and custom name
def execute(): Unit //do the task
}
當我使用TaskKey進行操作時,我的HashMap實際上是格柵,但實際上HashMap可以用ID訪問。所以,我必須定義另一個ConcurrentHashMap來將ID的地圖存儲到TaskKey中:
val auxiliaryMap = new ConcurrentHashMap[String, TaskKey]()
讓我們考慮一個添加和刪除操作:
def get(taskId: String) = {
Option(auxiliaryMap.get(taskId)).flatMap{x => //try get TaskKey
//if TaskKey exist, try get it.
Option(tasks.get(x)) //make null to None
}
}
def remove(taskId: String) = {
Option(auxiliaryMap.remove(taskId)).flatMap{ x => //try get TaskKey
//if TaskKey exist, try remove it.
Option(tasks.remove(x)) //make null to None
}
}
顯然,雖然這兩個地圖的是線程安全的,包裝使數據不一致性。如果我使用鎖定,多段地圖變得毫無意義。我該如何處理這個問題,使兩個ConcurrentHashMap運行良好?
此外,TaskKey包含用於對數據進行排序一個SYSTEMTIME變量,完全ConcurrentSkipListMap
定義爲這樣:
val tasks = new ConcurrentSkipListMap[TaskKey, Task](new Comparator[TaskKey]() {
override def compare(o1: TaskKey, o2: TaskKey): Int = {
val compare = (o1.systemTime - o2.systemTime).toInt
if (compare == 0) {
o1.hashCode() - o2.hashCode()
} else compare //distinct same time task
}
})
任何疑問,歡迎,如果我錯過了什麼。
你能說清楚你的意思嗎?當我使用TaskKey來操作我的HashMap是好的,但實際上,HashMap可以用ID很少訪問。*?有一些方法可以同步2個hashmaps,但最好是像最初所建議的那樣只使用一個。 – Augusto
@August,'get(taskId:String)'用於獲取Task對象。我必須在獲得Task之前獲得TaskKey。*幾乎不能*表示我不能直接使用TaskKey,只能得到數據與taskId字符串。這就是爲什麼我使用兩個HashMap。 – LoranceChen
我自己討厭這樣的評論,但我不禁要問。你確定你需要任務ID作爲一個字符串。也許只是使用TaskKey作爲任務ID並且只有一個地圖? –