Jas*_*son 5 java multithreading synchronization
我想在多个API请求上锁定一个对象,这样每个用户只能输入一个代码块.
是否synchronized(obj)基于对象的引用或它的锁定hashCode()功能?
我可以这样做:
synchronized("asdf") {
doSomethingNifty();
}
Run Code Online (Sandbox Code Playgroud)
这里"asdf"有一个唯一的哈希,但没有唯一的引用.
Gra*_*ray 12
synchronized(obj)是否基于对象的内存位置或其toHash()函数进行锁定?
都不是.它锁定在与对象关联的监视器上.就JVM而言,我们不讨论对象的内存地址,因为它是可重定位的,并且它不是哈希代码(即使在方面Object.hashcode()),因为它不是唯一的.
就你应该锁定的内容而言,它应该是同一个final对象.就像是:
private final Object lockObject = new Object();
...
synchronized (lockObject) {
// do stuff that needed to be protected
}
Run Code Online (Sandbox Code Playgroud)
您希望它final可以保证多个线程锁定在不更改的同一对象引用上. private很好,所以外面的类不能搞砸类内部的锁定.
这里"asdf"具有唯一的哈希,但没有唯一的内存地址.
"asdf"并不能有一个唯一的哈希,因为其他字符串可能具有相同的哈希值,它实际上可以在应用程序中有一个独特的"内存地址"跨越"ASDF"的所有用法如果编译器将其存储在Java字符串池.这意味着一些完全不同的类也可能具有相同的坏模式代码块,并且会影响类的同步,因为它将锁定在同一个String对象实例上.这就是private锁定对象如此重要的原因.
虽然我们关于这个问题,还必须永远像一个非最终的物体,像可变值同步Boolean或Integer.经常使用以下模式,这是非常错误的:
Boolean value = false;
...
// really bad idea
synchronized (value) {
if (value) {
value = false;
} else {
value = true;
}
}
Run Code Online (Sandbox Code Playgroud)
这是非常错误的,因为value引用正在改变.因此,一个线程可能会锁定它,然后更改它的引用值,以便另一个线程将锁定另一个对象,并且两个线程将同时在其中synchronized.更糟糕的是因为Boolean只有2个值true而且false是常量,因此多个类将锁定在相同的引用上.
| 归档时间: |
|
| 查看次数: |
1965 次 |
| 最近记录: |