【问题标题】:Is it possible to allow more number of threads than concurrency level in ConcurrentHashMap?是否可以在 ConcurrentHashMap 中允许比并发级别更多的线程?
【发布时间】:2017-04-12 09:56:30
【问题描述】:

假设我们有一个大小为 16 的 ConcurrentHashMap ,即并发级别 16。如果在此映射上工作的线程数大于 16,即在 20 到 25 之间,那么额外的线程会发生什么,无论它们是否处于等待状态?

如果是,那么它们将处于等待状态多长时间以及它们将如何在内部与其他线程通信?

【问题讨论】:

  • 你至少读过CHM的Javadoc吗?

标签: java multithreading synchronization thread-safety concurrenthashmap


【解决方案1】:

并发级别没有什么神奇之处。即使您的示例中的线程少于 16 个,它们在尝试访问地图时仍然可能发生冲突。

如果并发级别是 16,那么当任意两个线程尝试将两个不同的 key 放入 map 时,在 16 中将有一次机会将两个 key 分配到同一个段。如果是这种情况,那么他们对该段的访问将必须序列化。 (即,必须阻塞其中一个线程,直到另一个线程完成。)

当然,如果两个线程试图同时访问 same 键,那么保证他们将访问同一个段,其中一个将被阻塞,不无论并发级别如何。

额外线程是否处于等待状态会发生什么?

什么都没有。这就是synchronized 语句的作用。它什么都不做(也就是“阻塞”),直到锁可用。然后,它获取锁,执行语句体,并释放锁。

他们将处于等待状态多长时间?

在互斥锁上阻塞的线程将保持阻塞状态,直到该锁被其他线程释放。在设计良好的代码中,这应该只是非常很短的时间——刚好足够让其他线程更新一些字段。

在内部它们将如何与其他线程通信?

不确定您所说的“内部”是什么意思。被阻塞的线程无法与其他线程通信。在解锁之前,它不能做任何事情。

也许您在问操作系统如何知道要取消阻止的内容以及何时取消阻止。

当一个线程试图锁定一个已被其他线程使用的互斥锁时,操作系统将挂起该线程,保存其状态,并将一些代表该线程的令牌放入与该互斥锁关联的队列中.当线程的所有者释放互斥锁时,操作系统从队列中选择一个线程,将互斥锁的所有权转移给选定的线程,恢复线程的保存状态,并让它运行。

不同操作系统用来选择解除阻塞的线程的算法,以及保存和恢复线程上下文的方法(也称为“上下文切换”)是比我在这里讨论的空间或时间更深的主题。

【讨论】:

    猜你喜欢
    • 2016-06-22
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 2016-01-04
    相关资源
    最近更新 更多