Java 监视器锁的最低字节使用值是多少?

Java 监视器锁的最低字节使用值是多少?,java,multithreading,locking,Java,Multithreading,Locking,要在Java中使用内在锁定,您需要 Object o = new Object() ... sychronized (o) { ... } 因此,一个监视器已经需要一个对象,即(或12个字节用于压缩操作和64位) 现在假设您希望使用大量这些监视器,例如,用于具有比集合.synchronizedList更好并发性(基于条目)的and。那么,实现这一目标最有效的方法是什么?我可以用2个嵌套锁来锁定4个条目,还是用3个嵌套锁来锁定8个条目?或者我可以使用“每个线程一个锁”,例如在Concurren

要在Java中使用内在锁定,您需要

Object o = new Object()
...
sychronized (o) {
 ...
}
因此,一个监视器已经需要一个对象,即(或12个字节用于压缩操作和64位)


现在假设您希望使用大量这些监视器,例如,用于具有比
集合.synchronizedList
更好并发性(基于条目)的and。那么,实现这一目标最有效的方法是什么?我可以用2个嵌套锁来锁定4个条目,还是用3个嵌套锁来锁定8个条目?或者我可以使用“每个线程一个锁”,例如在
ConcurrentHashMap
中?

要获得监视器,您需要一个对象,因此要获得您想要的功能,即锁定一组基本值,您需要一个对象作为该组的对象

与其创建一个值数组并将值块视为一个集合,不如为监视器创建一个单独的
对象
,只需为值集合创建对象即可


这是面向对象的方式。

根据访问模式,您可以通过分割数据结构并使用一个内部锁来保护多个元素,从而使用较少的锁来提高并发性。此技术用于
java.util.concurrent
包中提供的一些并发集合

“我能不能用2个嵌套锁来表示4个条目,或者用3个嵌套锁表示8个条目等等?”听起来你打算把每个锁当作条目索引中的一个位来处理:如果设置了该位,则获取锁;如果清楚了,跳过它。这行不通。想想索引0。不会获得锁,也不会有并发控制

您可以通过将锁的数量增加一倍(每一位都有一个“set”和“clear”锁)来让它“工作”,但这仍然是一个坏主意,因为这样会浪费锁,导致并发性非常差。最外面的锁将保护一半的入口。随后获得的任何嵌套锁都是无用的,因为其他线程已经从该段中排除


这会让您回到对数据进行分段的过程,每个分段都有一个锁,就像
java.util.concurrency
那样。

如果您有一个引用数组,并且数组对象本身不需要同步,而只需要数组单元格中的单个引用值,那么您正在同步/锁定什么,所以你不需要同步,所以你这样做是为了在障碍发生之前建立,还是什么?这不是我的用例。数组中有多个int或byte值,必须作为“一个对象”处理。例如,假设您有一个巨大的坐标列表(纬度和经度),那么如果您使用引用,将浪费大量内存。值类型可能会解决这个问题,但在JVM中还不可用。将在帖子中对此进行澄清。@Karussell您签出StripedLock了吗??非常感谢!我还没听说过,但听起来已经不错了:)。。。你有解释的链接吗?到目前为止只能找到源代码(jboss等)。。。编辑:这就是你的意思吗?阅读上面提到的文章对我的情况没有帮助,因为我已经使用了类似的技术(对多个“行”使用相同的监视器锁),正如在评论中所解释的,这不是我想要的。我想要的是一个内存高效的数组或列表,对于这个列表,我需要一种内存高效的锁定方法:)非常感谢您尝试(或已经更好地理解)使用“位”的锁定思想。我们必须再考虑一下:)。是的,通过段使用更少的锁我已经做到了,但我不能做到极端,我必须弄清楚我的列表有多大,段大小是否足够小。java.util.concurrency在哪里使用这种段方法?我可以用
ConcurrentMap
为每个线程使用一个锁吗。。。不知何故:)?@Karussell
ConcurrentHashMap
在Java 7中使用了它,但在Java 8中似乎使用了不同的方法,而
Segment
的保留只是为了支持与旧版本的序列化兼容性。每个线程一个锁。。。我不明白。如果每个线程只尝试获取自己的锁,那么它总是会成功,就像没有锁一样。我猜不出你的意思。谢谢你的回复,很抱歉这里没有太多描述。我的意思是,如果我在线程“进入”特定数组索引之前检查线程的锁(从
C..H..Map
),然后在“离开”之后将其解锁,然后将其从映射中移除(以节省内存)。这意味着读取线程将看到相同的锁和块,如果
null
,则返回。我希望CHMap能帮上忙,但担心这不太可能或非常复杂,无法让它保持快速(乐观锁定?)。但是仍然认为有些数据结构的锁与线程数量成比例,而不是数组索引。我明白了。我还没有仔细考虑过这一点,也没有看到你所描述的工作示例,但我认为这是可能的。我会再考虑一下。