Java 同步块——锁定对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18156954/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java synchronized blocks -- lock objects
提问by Roam
In the sample code
在示例代码中
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) {
c1++;
}
}
public void inc2() {
synchronized(lock2) {
c2++;
}
}
}
on thispage,
在这个页面上,
lock1and lock2are controlling the updates on c1and c2resply.
lock1和lock2正在控制c1和c2回复上的更新。
However,
然而,
synchronized(lock2)
is acquiring the lock of the object lock1and releasing it when the synchronized block
正在获取对象lock1的锁并在同步块时释放它
synchronized(lock1) {
c1++;
}
is executed.
被执行。
While this block is being executed, there may be an update on member c1of thisobject still-- and I don't see how this update is being prevented by synchronizing on lock1as in the code.
当正在执行该块,有可能是在构件的更新C1的此目的和still--我看不出是由上同步防止此更新锁1中的代码。
It is the object lock1that there is exclusive access on-- and nothing else(?)
对象lock1有独占访问权限——除此之外别无他物(?)
So, how is the implementation
那么,执行情况如何
public void inc1() {
synchronized(lock1) {
c1++;
}
}
in the above code different from
在上面的代码中不同于
public void synchronized inc1() {
c1++;
}
or even
甚至
public void inc1() {
synchronized(c1) {
//do something on c1
}
}
when c1is an object but not a primitive?
当c1是一个对象而不是一个原始类型时?
What am I missing here ?
我在这里错过了什么?
Note: I saw
注:我看到了
What is the difference between synchronized on lockObject and using this as the lock?
在 lockObject 上同步和使用 this 作为锁有什么区别?
and
和
Java synchronized method lock on object, or method?
among some other discussions.
在其他一些讨论中。
采纳答案by rgettman
Implementation 1.
实施 1.
You are locking on the lock1
object. Nothing else that needs a lock on lock1
can execute. Having your two methods lock on different objects means that the two methods can run concurrently, but no two threads can run the same method concurrently.
您正在锁定lock1
对象。没有其他需要锁定的东西lock1
可以执行。将两个方法锁定在不同的对象上意味着这两个方法可以并发运行,但没有两个线程可以同时运行相同的方法。
Implementation 2.
实施 2.
Making a method synchronized
means that the entire method body is implicitly in a synchronized(this)
block (or synchronized on the Class
object if the method is static
. If both methods are synchronized
, then one method would prevent the other from running at the same time, which is different then locking both methods on different objects.
创建一个方法synchronized
意味着整个方法体隐式在一个synchronized(this)
块中(如果方法是,则在Class
对象上同步static
。如果两个方法都是synchronized
,那么一个方法会阻止另一个同时运行,这与锁定两者不同不同对象的方法。
Implementation 3.
实施 3.
If c1
is an object and not a primitive, then the semantics are very similar to implementation 1 - locking on an explicit object.
如果c1
是对象而不是原语,则语义与实现 1 非常相似 - 锁定显式对象。
回答by Martijn Courteaux
Your statement is as far as I know incorrect. The page you linked doesn't state what you claim in your question neither. This is how locks work: Locks do notprevent threads of accessing an object at all. Locks only prevents another thread of acquiring the same lockwhile another thread already has acquired that lock.
据我所知,你的说法是错误的。您链接的页面也没有说明您在问题中声称的内容。这就是锁的工作原理:锁根本不会阻止线程访问对象。锁只会阻止另一个线程获取相同的锁,而另一个线程已经获取了该锁。
This means that this can happen:
这意味着这可能发生:
Thread A: synchronize (lockObject)
Thread B: lockObject.toString();
Thread A: release the lock on lockObject
This is what happens when two Threads want the same lock at the same time:
当两个线程同时想要同一个锁时会发生这种情况:
Thread A: synchronize (lockObject)
Thread B: synchronize (lockObject) // This will block until (1) !
Thread A: do some stuff and then release lock on lockObject
Thread B: gets the lock (1)
However:
然而:
public void synchronized inc1() {
c1++;
}
is exactly the same as:
完全相同:
public void inc1() {
synchronized(this) {
c1++;
}
}
回答by chrylis -cautiouslyoptimistic-
Marking a block or method synchronized
without specifying a lock object synchronizes on the object who owns the method; in this case, the MsLunch
instance. It's equivalent to synchronized(this)
. The purpose of the lock-object idiom is to break that lock up so that c1
and c2
can be manipulated separately. A synchronized
block can only synchronize on an object, not a primitive.
在synchronized
不指定锁对象的情况下标记块或方法会在拥有该方法的对象上同步;在这种情况下,MsLunch
实例。它相当于synchronized(this)
. 锁定对象习语的目的是打破锁定,以便c1
和c2
可以单独操作。一个synchronized
块只能在一个对象上同步,而不是一个基元。
回答by bolei
synchronized(lock2){
// do sth
}
is actually acquiring lock of object lock2
实际上是获取对象lock2的锁
where as
然而
public void synchronized inc1() {
c1++;
}
acquires object on this object.
获取此对象上的对象。
locks acquired by synchronized will be released once the program leaves the block.
一旦程序离开块,synchronized 获取的锁将被释放。
回答by sadjkas sadal
I was having trouble with one thread hogging the lock
我在一个线程占用锁时遇到了麻烦
for(;;){synchronized(lockObject){
...
}}
I guess Java doesn't like to unlock it on its own the first chance it gets.
我猜 Java 不喜欢第一次有机会就自己解锁它。
Using an java.util.concurrent.locks.ReentrantLock fixed the problem
使用 java.util.concurrent.locks.ReentrantLock 解决了这个问题
static ReentrantLock lock = new ReentrantLock();
for(;;){
lock.lock();
...
lock.unlock();
}