java 块级同步
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/875175/
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
Block level synchronization
提问by Madan
What is the significance of parameter passed to synchronized?
传递给synchronized的参数有什么意义?
synchronized ( parameter )
{
}
to achieve block level synchronization. Somewhere i saw code like
实现块级同步。在某处我看到了类似的代码
class test
{
public static final int lock =1;
...
synchronized(lock){
...
}
}
I don't understand the purpose of this code.
我不明白这段代码的目的。
Can anyone give me a better example and/or explain it?
谁能给我一个更好的例子和/或解释它?
回答by Jon Skeet
It's the reference to lock on. Basically two threads won't execute blocks of code synchronized using the same reference at the same time. As Cletus says, a synchronized methodis mostly equivalent to using synchronized (this)inside the method.
这是锁定的参考。基本上两个线程不会同时执行使用相同引用同步的代码块。正如 Cletus 所说,同步方法大多相当于在方法synchronized (this)内部使用。
I very much hope that the example code you saw wasn't quitelike that - you're trying to synchronize on a primitive variable. Synchronization only works on a monitor (via a reference) - even if it werelegal code, xwould be boxed, which would lead to some veryodd behaviour, as some integers will always be boxed to the same references, and others will create a new object each time you box. Fortunately, the Java compiler realises this is a very bad idea, and will give you a compile-time error for the code you've posted.
我非常希望,示例代码,你看到的是不是很喜欢-你正在尝试同步上基本变量。同步仅适用于监视器(通过引用) - 即使它是合法代码,x也会被装箱,这将导致一些非常奇怪的行为,因为某些整数将始终被装箱到相同的引用,而其他整数将创建一个新的每次装箱时都有对象。幸运的是,Java 编译器意识到这是一个非常糟糕的主意,并且会为您发布的代码提供编译时错误。
More reasonable code is:
更合理的代码是:
class Test
{
private static final Object lock = new Object();
...
synchronized(lock){
...
}
}
I've made the lock private, and changes its type to Object. Whether or not it should be static depends on the situation - basically a static variable is usually used if you want to access/change static data from multiple threads; instance variables are usually used for locks when you want to access/change per-instance data from multiple threads.
我已将锁设为私有,并将其类型更改为Object. 是否应该是静态的取决于具体情况——基本上,如果您想从多个线程访问/更改静态数据,通常会使用静态变量;当您想从多个线程访问/更改每个实例的数据时,实例变量通常用于锁定。
回答by cletus
This:
这:
public synchronized void blah() {
// do stuff
}
is semantically equivalent to:
在语义上等同于:
public void blah() {
synchronized (this) {
// do stuff
}
}
Some people don't like to use 'this' for synchronization, partly because it's public (in that the instance is visible to external code). That's why you end up with people using private locks:
有些人不喜欢使用“this”进行同步,部分原因是它是公开的(因为该实例对外部代码可见)。这就是为什么您最终会使用私人锁的原因:
public class Foo
private final static String LOCK = new String("LOCK");
public void blah() {
synchronized (LOCK) {
// do stuff
}
}
}
The benefit is that LOCK is not visible outside the class plus you can create several locks to deal with more fine-grained locking situations.
好处是 LOCK 在类之外不可见,而且您可以创建多个锁来处理更细粒度的锁定情况。
回答by Lasse V. Karlsen
The purpose of the synchronizedstatement (ref: here) is to make sure that in a multi-threaded application, only one thread can access a critical data structure at a given time.
该synchronized语句(参考:此处)的目的是确保在多线程应用程序中,在给定时间只有一个线程可以访问关键数据结构。
For instance, if you let two threads change the same data structure at the same time, the data structure would be corrupted, then you typically protect it with a lock.
例如,如果您让两个线程同时更改相同的数据结构,则该数据结构会被破坏,那么您通常会使用锁来保护它。
In the real world, consider an analog where a public toilet has a key, hanging in a central place. Before you can use the toilet, you need the key, not only to enter, but it's also a guarantee that nobody else will try to enter the same toilet at the same time. They'll have to wait for the key to become available.
在现实世界中,请考虑一个模拟,其中公共厕所有一把挂在中央位置的钥匙。在上厕所之前,你需要钥匙,不仅可以进入,而且还可以保证没有其他人会同时尝试进入同一个厕所。他们将不得不等待密钥可用。
This is how such a lock construct works.
这就是这种锁结构的工作原理。
The parameter to the synchronizedkeyword is the key in this case. You lock the key, do what you need to do, then you unlock the key to let others have access to it. If other threads tries to lock the key while it is currently being locked by another thread, that thread will have to wait.
synchronized在这种情况下,关键字的参数是关键。你锁上钥匙,做你需要做的事,然后你解锁钥匙让其他人可以访问它。如果其他线程试图锁定当前正在被另一个线程锁定的密钥,则该线程将不得不等待。
回答by Peter Lawrey
I can't explain it as it doesn't compile. You cannot lock a primitive.
我无法解释它,因为它无法编译。您不能锁定原语。
Another bad example would be to change it to
另一个不好的例子是将其更改为
public static final Integer lock =1;
This is a bad idea as small auto-boxed primitives are cached and is likely to have strange side effects (if this is done more than once)
这是一个坏主意,因为小的自动装箱原语被缓存并且可能会产生奇怪的副作用(如果这样做不止一次)
回答by Macker
The object instance that is passed in to synchronized is the "unit of locking". Other threads that execute that try to gain a lock on the same instance will all wait their turn.
传入 synchronized 的对象实例是“锁定单元”。其他试图在同一实例上获得锁的执行线程都将等待轮到它们。
The reason people use this rather than the method level synchronized keyword (which locks on the executing class object's instance) is that they might want a finer-grained or different thing to wait for locking on, depending on how their multi-threaded algorithm is designed.
人们使用 this 而不是方法级别的 synchronized 关键字(锁定正在执行的类对象的实例)的原因是他们可能想要一个更细粒度或不同的东西来等待锁定,这取决于他们的多线程算法是如何设计的.

