同步方法和同步块有什么区别?

8

synchronized 方法和 synchronized 语句有什么区别?

如果可以,请举个例子来说明。


我认为PartlyCloudy的回答是最简洁的。 - Adrian Pronk
5个回答

13

同步方法锁定与类实例相关的监视器(即'this')或类(如果是静态方法),并阻止其他人在从该方法返回之前锁定。同步块可以锁定任何监视器(您告诉它哪个),并且其作用域可以小于封闭方法的作用域。

如果同步块不等同于整个方法的范围和/或锁定的内容不像实例(或静态类)那么严格,则更倾向于使用同步块。


8

JLS(Java 语言规范)中的引用(包括示例):

JLS 14.19 synchronized 语句块

synchronized 语句块代表执行线程获取互斥锁、执行代码块,然后释放锁。当执行线程拥有锁时,其他线程无法获取该锁。

synchronized 方法

A synchronized method acquires a monitor before it executes. For a class (static) method, the monitor associated with the Class object for the method's class is used. For an instance method, the monitor associated with this (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语句将同步限制在仅在需要时才进行同步(即当您访问共享的可变数据时)。


4

synchronized 方法是一个方法,其方法体自动封装在 synchronized 块中。

因此,以下两个代码片段是相同的:

public void foo()
{
    synchronized (this)
    {
        bar();
    }
}

public synchronized void foo()
{
    bar();
}

3

synchronized在方法上使用时会锁定一个this对象。它等同于synchronized (this) {}

标准的synchronized是锁定指定的对象/监视器。使用synchronized (***) {},您可以选择一个对象用于锁定。


2

同步方法是指您实际上将整个函数体放置在同步块中的方法。同步块的优点在于,您可以将同步块应用于函数中的一些选择性语句,而不是整个函数。通常情况下,最好使同步块尽可能短,因为在同步块中花费的时间是其他线程可能无法执行有意义工作的时间。另一个区别在于,使用同步块时可以指定要应用锁的特定对象,而使用同步方法时,对象本身自动用作执行同步的锁。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接