java - Java Synchronized 如何比较锁定的对象?

标签 java multithreading synchronization

我想通过多个 API 请求锁定一个对象,这样每个用户只有一个请求可以输入一段代码。

synchronized(obj) 是否基于对象的引用或其 hashCode() 函数进行锁定?

即我能做吗:

synchronized("asdf") {
    doSomethingNifty();
}

这里“asdf”有一个唯一的散列但没有唯一的引用。

最佳答案

Does synchronized(obj) lock based on the object's memory location or its toHash() function?

都没有。它锁定与对象关联的监视器。就 JVM 而言,我们不讨论对象的内存地址,因为它是可重定位的,而且它不是哈希码(即使在 Object.hashcode() 方面),因为它不是唯一的。

就您应该 锁定的内容而言,它应该是相同的 final 对象。像这样的东西:

private final Object lockObject = new Object();
...
synchronized (lockObject) {
   // do stuff that needed to be protected
}

您希望它是final 以便可以保证多个线程锁定在同一个未更改的对象引用上。 private 很好,因此外部类不能搞砸类内部的锁定。

Here "asdf" has a unique hash but no unique memory address.

“asdf” 有一个唯一的散列,因为其他字符串可能有相同的散列,它实际上可能有一个唯一的“内存”如果编译器将它存储在 Java string pool 中,则应用程序中所有使用“asdf”的地址” .这意味着一些完全不同的类也可能具有相同的错误模式代码块,并且会影响您的类的同步,因为它会锁定在相同的 String 对象实例上。这就是为什么 private 锁对象如此重要。

当我们讨论这个主题时,您也绝不能同步可变值,例如 BooleanInteger 等非最终对象。下面的模式经常被使用并且是非常错误的:

Boolean value = false;
...
// really bad idea
synchronized (value) {
   if (value) {
      value = false;
   } else {
      value = true;
   }
}

这是非常错误,因为value 引用正在改变。所以一个线程可能会锁定它,然后更改它的引用值,这样另一个线程会锁定另一个对象,并且两个线程会同时在 synchronized 中。更糟糕的是,对于 Boolean,只有 truefalse 这两个值是常量,因此多个类将锁定相同的引用。

关于java - Java Synchronized 如何比较锁定的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16675005/

相关文章:

java - Apache Mina 执行器过滤器

java - .properties 文件中的条件语句

java - 多线程基准测试

python - 使用 py2app 构建 PySide 应用程序包时,QApplication 未在主线程中运行

java - 检查 java 线程是否已被 join()ed

java - 同步可以作为AOP中的一个方面吗

c# - 用于 Java 的 OnPaint()?

php - 获取过去某个时间点的粉丝页面的 Facebook 点赞数

java - Android Thread Concourrency UI线程编辑一个变量,其他线程读取相同的变量

c++ - 实现线程监控机制所需的帮助