java - 如何在java/scala中锁定免费使用两个ConcurrentHashMap?

标签 java multithreading scala concurrenthashmap

这个问题我很头疼,希望能得到一些帮助。
我想用 ConcurrentSkipListMap 存储许多 Task ,其内部是 ConcurrentHashMap ,称为多段锁。
简单的示例代码用 scala 展示(java 也可读):
val 任务 = 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的映射:
valauxiliaryMap = 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都是线程安全的,但包装器使数据不一致。如果我使用锁,多段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
  }
})

如果我遗漏了什么,欢迎提出任何问题。

最佳答案

我正在使用消息队列将运算符扁平化到这些映射。此外,这种方式根本不需要并发 HashMap ,但消息队列可能需要并发队列。

关于java - 如何在java/scala中锁定免费使用两个ConcurrentHashMap?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38651686/

相关文章:

java - 从 Travis 中排除测试

java - JPanel 组件在尝试刷新后消失

java - 为什么 equals 可能不会返回 true

java - 如何将 apache-camel DSL 与线程池一起使用?

java - 当变量在多个类中发生更改时,如何同步对变量的访问?

java - 将相机预览与图像合并?

c++ - QT 线程问题...有些东西正在拖延 GUI 响应

scala - 从Play框架(Scala)中的play.api.mvc.Action [AnyContent]获取响应正文

json - 使用Play Framework JSON库自定义JodaTime序列化?

Scala:包含类型的变量