synchronized
方法和 synchronized
语句有什么区别?
如果可以,请举个例子来说明。
synchronized
方法和 synchronized
语句有什么区别?
如果可以,请举个例子来说明。
同步方法锁定与类实例相关的监视器(即'this')或类(如果是静态方法),并阻止其他人在从该方法返回之前锁定。同步块可以锁定任何监视器(您告诉它哪个),并且其作用域可以小于封闭方法的作用域。
如果同步块不等同于整个方法的范围和/或锁定的内容不像实例(或静态类)那么严格,则更倾向于使用同步块。
JLS(Java 语言规范)中的引用(包括示例):
synchronized
语句块
synchronized
语句块代表执行线程获取互斥锁、执行代码块,然后释放锁。当执行线程拥有锁时,其他线程无法获取该锁。
synchronized
方法A
synchronized
method acquires a monitor before it executes. For a class (static
) method, the monitor associated with theClass
object for the method's class is used. For an instance method, the monitor associated withthis
(the object for which the method was invoked) is used.These are the same locks that can be used by the
synchronized
statement; thus, the code:
class Test { int count; synchronized void bump() { count++; } static int classCount; static synchronized void classBump() { classCount++; } }
has exactly the same effect as:
class BumpTest { int count; void bump() { synchronized (this) { count++; } } static int classCount; static void classBump() { try { synchronized (Class.forName("BumpTest")) { classCount++; } } catch (ClassNotFoundException e) { ... } } }
那么它们有什么不同之处?
引用自《Effective Java 2nd Edition》第67条:避免过度同步:
通常情况下,您应该尽可能少地在
synchronized
区域内执行工作。
synchronized
方法修饰符是一种语法糖,适用于许多但不是所有场景。该书详细讨论了为什么应该避免过度同步,但基本上通过使用synchronized
语句,您可以更好地控制synchronized
区域的边界(如果情况需要,您还可以选择自己的锁)。
除非您的方法非常简单和/或您需要在整个方法的持续时间内获取this
锁(如果该方法是static
,则获取Class
对象锁),否则应使用synchronized
语句将同步限制在仅在需要时才进行同步(即当您访问共享的可变数据时)。
synchronized
方法是一个方法,其方法体自动封装在 synchronized
块中。
因此,以下两个代码片段是相同的:
public void foo()
{
synchronized (this)
{
bar();
}
}
public synchronized void foo()
{
bar();
}
synchronized
在方法上使用时会锁定一个this
对象。它等同于synchronized (this) {}
标准的synchronized
是锁定指定的对象/监视器。使用synchronized (***) {}
,您可以选择一个对象用于锁定。
同步方法是指您实际上将整个函数体放置在同步块中的方法。同步块的优点在于,您可以将同步块应用于函数中的一些选择性语句,而不是整个函数。通常情况下,最好使同步块尽可能短,因为在同步块中花费的时间是其他线程可能无法执行有意义工作的时间。另一个区别在于,使用同步块时可以指定要应用锁的特定对象,而使用同步方法时,对象本身自动用作执行同步的锁。