我很久以前就对这个问题感到头疼,希望真的能有所帮助。
我想用Task存储许多ConcurrentSkipListMap,其中的内部是ConcurrentHashMap,称为多段锁。
用scala展示的简单示例代码(java也可读):
val tasks = new ConcurrentSkipListMap[TaskKey, Task]()
将类简称为:

class TaskKey(id: String, systemTime: Long)
用于标识Task的TaskKey类是唯一的,并且Task如下:

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
  }
}


显然,尽管Map都是线程安全的,但包装器使数据不一致。如果使用锁,则多段映射将变得毫无意义。如何解决使两个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
  }
})


如果我想念任何东西,欢迎任何问题。

最佳答案

我正在使用消息队列将操作员平整到这些maps。此外,这种方式根本不需要并发hashmap,但是消息队列可能需要并发队列。

10-06 14:46