java 关于Java同步的问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6214229/
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
Question about Java synchronized
提问by bethesdaboys
The Java documentation says that "it is not possible for two invocations of synchronized methods on the same object to interleave". What I need to know is whether synchronized will also prevent a synchronized method in two different instances of the same classfrom interleaving.
Java 文档说“对同一对象的同步方法的两次调用不可能交错”。我需要知道的是,synchronized 是否还会阻止同一类的两个不同实例中的同步方法交错。
E.g. class Worker has method called process(). We have several instances of Worker running in their own threads. We want to prevent more than one instance running the process() method simultaneously. Will synchronizeddo this?
例如,Worker 类有一个名为 process() 的方法。我们有几个 Worker 实例在它们自己的线程中运行。我们希望防止多个实例同时运行 process() 方法。将同步做到这一点?
Thanks.
谢谢。
回答by Aasmund Eldhuset
No; synchronized
only prevents multiple threads from simultaneously executing the method in the sameinstance. If you have ninstances, there could be nthreads, each executing the method in one of the instances.
不; synchronized
仅防止多个线程在同一实例中同时执行该方法。如果您有n 个实例,则可能有n 个线程,每个线程在其中一个实例中执行该方法。
If you need to ensure that only one thread may execute the method across all instances, you should make the method static
, or make the method non-synchronized
and rather use a synchronized
block inside the method to lock on a private static
field.
如果您需要确保只有一个线程可以在所有实例中执行该方法,则应该使该方法static
成为非方法synchronized
,而是使用synchronized
方法内部的块来锁定某个private static
字段。
Edit: Note that synchronizing on a private
instance variable is preferrable to having a synchronized
method or to synchronize on this
, and that locking on a private static
instance variable is preferrable to having a static synchronized
method or an instance method that synchronizes on this.getClass()
. The reason is that this
and this.getClass()
are object references that are accessible throughout the program, so anybody may synchronize on these objects, and thereby block threads that want to call your method.
编辑:请注意,同步private
实例变量比拥有synchronized
方法或同步更可取this
,锁定private static
实例变量比拥有static synchronized
同步方法或实例方法更可取this.getClass()
。原因是this
和this.getClass()
是在整个程序中都可以访问的对象引用,因此任何人都可以在这些对象上进行同步,从而阻止想要调用您的方法的线程。
Edit: Also, see @Cowan's comment below - summary: if you really want to lock on the class, you might want to use synchronized (Worker.class)
rather than synchronized (this.getClass())
, depending on what effect you want in the case of subclassing.
编辑:另外,请参阅下面@Cowan 的评论 - 摘要:如果您真的想锁定该类,您可能想要使用synchronized (Worker.class)
而不是synchronized (this.getClass())
,这取决于您在子类化的情况下想要的效果。
回答by Swaranga Sarma
No, synchronized will not do this. More specifically synchronized on the instance level will not do this. Instead you will have to synchronize on the class level.
不,同步不会这样做。更具体地说,在实例级别同步不会这样做。相反,您必须在类级别上进行同步。
For example instead of having:
例如,而不是:
public synchronized method()
{
//do stuff
}
You will have to code as:
您必须编码为:
public void method()
{
synchronized(this.getClass())
{
//do stuff
}
}
回答by GKelly
No, the method synchronized locks on the specific object (the 'this'), so 2 instances of the same class would lock on different objects.
不,该方法同步锁定特定对象('this'),因此同一类的 2 个实例将锁定不同的对象。
If you want to synchronize across all instances of a class, you need to use a synchronized block IN the method, locking on a static final object.
如果要跨类的所有实例进行同步,则需要在方法中使用同步块,锁定静态最终对象。
回答by Mat
Not unless the method is static
. A synchronized
non-static method takes a lock on the object (instance) on which it is invoked, not on the class.
除非方法是static
. 阿synchronized
非静态方法以在其上调用,而不是在类上的对象(实例)的锁。
A synchronized static method takes a lock on the class, so that could help - but it's often not very practical.
同步静态方法需要对类进行锁定,因此这可能会有所帮助 - 但它通常不是很实用。
What you could do is have a static member object in your class, and do a synchronized block on that (class-global) object in your process
method.
您可以做的是在您的类中有一个静态成员对象,并在您的process
方法中对该(类全局)对象执行同步块。
回答by Nik
If you make the method process
static, it would only allow one invocation of the method at the same time.
如果您将方法process
设为静态,则它只允许同时调用一次该方法。
If that is not possible, have a static variable, say Integer lock
;
And use synchronized (lock)
inside your method process
.
that is
如果这是不可能的,有一个静态变量,比如Integer lock
;并synchronized (lock)
在您的方法中使用process
。那是
process()
{
synchronized (lock)
{
// all your code
}
}
回答by Liv
I slightly disagree with Aasmund -- though agree a bit at the same time: If you use a construct like this:
我有点不同意 Aasmund——尽管同时有点同意:如果你使用这样的结构:
class Worker {
...
public synchronized void process() {...}
}
then Aasmund is right -- that won't prevent multiple instances of the Worker
class to execute process()
in parallel.
However, you can use the synchronized
keyword still to synchronize on a static member to prevent that from happening:
那么 Aasmund 是对的——这不会阻止Worker
类的多个实例process()
并行执行。但是,您可以使用synchronized
关键字 still 同步静态成员以防止发生这种情况:
class Worker {
static Object o = new Object();
...
public void process() {
synchronized(o) {
...//perform the work here
}
}
回答by Peter Lawrey
Only one thread can hold a lock on an object at any one time.
任何时候只有一个线程可以持有一个对象的锁。
A synchronized method attempt to hold a lock on the instance. Another thread can also hold a lock on another instance of the same class. Another thread cannot enter another synchronized method of the same instance. i.e. it is not the method which is locked.
同步方法尝试在实例上持有锁。另一个线程也可以持有同一个类的另一个实例的锁。另一个线程不能进入同一个实例的另一个同步方法。即它不是被锁定的方法。
However a thread can enter a non-synchronized method while another thread holds a lock on that object. Only synchronized methods are protected.
然而,一个线程可以进入一个非同步方法,而另一个线程持有该对象的锁。只有同步方法受到保护。
A static synchronized method obtains a lock on the Class rather than the object. However, the follows the same rules as non-static method except with a different object.
静态同步方法获取的是类而不是对象的锁。但是,除了使用不同的对象外,遵循与非静态方法相同的规则。
Note: There is no "instance" for static method even though you can write code which appears to use an instance. e.g. instance.staticMethod()
注意:即使您可以编写似乎使用实例的代码,也没有静态方法的“实例”。例如instance.staticMethod()