2016-07-29 32 views
1

很久以前我很頭疼,希望有一些幫助。
我想存儲很多TaskConcurrentSkipListMap其中內部是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 
    } 
}) 

任何疑問,歡迎,如果我錯過了什麼。

+2

你能說清楚你的意思嗎?當我使用TaskKey來操作我的HashMap是好的,但實際上,HashMap可以用ID很少訪問。*?有一些方法可以同步2個hashmaps,但最好是像最初所建議的那樣只使用一個。 – Augusto

+0

@August,'get(taskId:String)'用於獲取Task對象。我必須在獲得Task之前獲得TaskKey。*幾乎不能*表示我不能直接使用TaskKey,只能得到數據與taskId字符串。這就是爲什麼我使用兩個HashMap。 – LoranceChen

+0

我自己討厭這樣的評論,但我不禁要問。你確定你需要任務ID作爲一個字符串。也許只是使用TaskKey作爲任務ID並且只有一個地圖? –

回答

0

我正在使用消息隊列將運算符平鋪到這些maps.besides,這種方式根本不需要concurrenthashmap,但消息隊列可能需要一個併發隊列。