使用同步块
在方法 1 和方法 2 中使用同步块有什么区别或影响?
class A
{
private Object lock = new Object();
...
...
private void method1()
{
synchronized(A.class)
{
.....
}
}
private void method2()
{
synchronized(lock)
{
....
}
}
}
What is the difference or impact between using the synchronized block as in method1 and method2?
class A
{
private Object lock = new Object();
...
...
private void method1()
{
synchronized(A.class)
{
.....
}
}
private void method2()
{
synchronized(lock)
{
....
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在第一种方法中,使用 A 类的任何实例的所有线程都将被同步。
在第二种方法中,所有使用 A 类实例的线程都将被同步。
In first method all threads that use ANY instance of the class A will be syncronised.
In second method all threads that use THIS instance of the class A will be syncronised.
由于
A.class
可供其他人使用,因此它实际上是公共的。如果其他东西使用它来同步对某些代码部分的访问,那么您的代码部分可能会被阻止。这可能是好事,也可能是坏事;但你无法控制它。使用内部对象可以让您将其设为私有,以便您可以完全控制它的使用地点和时间。我更喜欢使用我可以控制的内部对象。
Since
A.class
is avaliable to others, it is public in effect. If something else uses it to synchronize access to some section of code then your section of code could be blocked. This might be good or bad; but you don't have control over it.Using an internal object allows you to decare it as private so that you have complete control over where and when it is used. I prefer to use an internal object that I have control.
Lock是一个普通的字段。因此“A”的每个实例都有一个。 A.class对于整个JVM来说是全局的。所以这两个块具有完全不同的语义。带有“lock”的版本表示,“对于 A 的这个实例,这个块中只能有一个线程”。 A.class 的版本表示“对于 A 的任何实例,此块中只能有一个线程。”
Lock is an ordinary field. So there is one of it for each instance of 'A'. A.class is global to the whole JVM. So the two blocks have completely different semantics. The version with 'lock' says, 'only one thread can be in this block for this instance of A'. The version with A.class says 'only one thread can be in this block for any instance of A.
在第一种情况下,您在公共对象 (
A.class
) 上进行同步,因此应用程序的其他部分可能会导致问题,因为它们也在A.class
上进行同步。在第二种情况下,您在私有锁对象上进行同步,从而确保没有其他人使用该锁来同步对其他对象的访问。
此外,如其他答案所示,该类的所有实例将在同一个锁上与第一个解决方案同步,而每个实例将拥有自己的与第二个解决方案的锁。
因此,第二种解决方案是更可取的(尽管锁对象应该是最终的)。
In the first case, you synchronize on a public object (
A.class
), and so other parts of the application might cause problems because they also synchronize onA.class
.In the second case, you synchronize on a private lock object, and are thus sure that nobody else uses the the lock to synchronize access to something else.
Moreover, as indicated in other answers, all the instances of the class will be synchronized on the same lock with the first solution, whereas each instance will have its own lock with the second solution.
The second solution is thus much preferred (although the lock object should be final).
需要同步块的参数才能创建多个“命名”块。因此,使用特殊的锁对象可能更灵活:您可以在将来创建lock1和lock2。
另一方面是等待和通知。您可以从另一个线程中调用
lock.wait()
,然后调用lock.notfify()
。在这种情况下你也可以使用两种方式(特殊的锁对象或A.class作为锁)。The parameter of synchronized block is needed to be able to create several "named" blocks. So using special lock object is probably more flexible: you can create lock1 and lock2 in future.
Yet another aspect is waiting and notification. You can say
lock.wait()
and thenlock.notfify()
from another thread. In this case you can also use both ways (special lock object or A.class as a lock).