这个问题在这里已经有一个答案:

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

我一直在网上搜索答案,人们似乎不确定这一点:-(

我的看法是,两者之间没有区别,除了同步块可能更本地化在范围中,因此锁定的时间较小?

如果锁定静态方法的锁定,则锁定是什么?上课的锁是什么意思?

有帮助吗?

解决方案

同步方法将方法接收器用作锁(即 this 对于非静态方法,以及用于静态方法的封闭类)。 Synchronized 块将表达式用作锁。

因此,以下两种方法等同于锁定前瞻性:

synchronized void mymethod() { ... }

void mymethod() {
  synchronized (this) { ... }
}

对于静态方法,该类将被锁定:

class MyClass {
  synchronized static mystatic() { ... }

  static mystaticeq() {
    syncrhonized (MyClass.class) { ... }
  }
}

对于同步块,您可以使用任何非 -null 对象作为锁:

synchronized (mymap) {
  mymap.put(..., ...);
}

锁定范围

对于同步方法,将在整个方法范围内保存锁,而在 synchronized 块,仅在该块范围(否则称为临界部分)中保存锁。实际上,允许JVM通过将某些操作从该操作中删除来进行优化 synchronized 如果可以证明可以安全地进行执行,则阻止执行。

其他提示

同步方法是速记。这个:

class Something {
    public synchronized void doSomething() {
        ...
    }

    public static synchronized void doSomethingStatic() {
        ...
    }
}

就所有意图和目的而言,等同于此:

class Something {
    public void doSomething() {
        synchronized(this) {
            ...
        }
    }

    public static void doSomethingStatic() {
        synchronized(Something.class) {
            ...
        }
    }
}

(在哪里 Something.class 是类的类对象 Something.)

因此,确实,使用同步块,您可以更具体地说明自己的锁定,并且更细化了何时要使用它,但除此之外,没有区别。

是的,这是一个区别。另一个是您可以在其他对象上获取锁 this.

关键区别在于:如果您声明了一种要同步的方法,则该方法的整个主体都会同步;但是,如果使用同步块,则可以在同步块中仅包围该方法的“临界部分”,同时将其余的方法排除在块之外。

如果整个方法是关键部分的一部分,则实际上没有区别。如果不是这种情况,则应仅在关键部分周围使用同步块。您在同步块中拥有的陈述越多,您获得的整体平行性就越少,因此您希望将其保持在最低限度。

对象实例上的同步方法锁定该方法包含在中。

作为同步块可以锁定任何对象的地方 - 通常是定义为实例变量的静音or。这可以对正在运行的锁进行更多控制。

我的看法是,两者之间没有区别,除了同步块可能更本地化在范围中,因此锁定的时间较小?

是的。你说的对。与众不同 synchronized 方法,同步语句必须指定提供内在锁定的对象。

Java教程的示例:

public void addName(String name) {
    synchronized(this) {
        lastName = name;
        nameCount++;
    }
    nameList.add(name);
}

同步语句也可用于改善与细粒度同步的并发性。您可以在以下用例的同一教程页面上找到好的示例。

例如,假设类 MsLunch 有两个实例字段C1和C2,它们从未一起使用。这些字段的所有更新必须是 synchronized, ,但是没有理由阻止C1更新与C2的更新交织在一起,并通过创建不必要的阻止来减少并发。 我们不使用同步方法或以其他方式使用与此关联的锁一起创建两个对象以提供锁.

如果锁定静态方法的锁定,则锁定是什么?上课的锁是什么意思?

在这种情况下,线程将获取与类关联的类对象的固有锁定。因此,对类的静态字段的访问受锁的控制,该锁与锁定的任何实例都不同。

当您将方法作为 同步 (非 static ) :

两个调用不可能 synchronized 同一对象上的方法交织。当一个线程为对象执行同步方法时,所有其他线程调用同一对象块(暂停执行)的同步方法,直到使用对象完成第一个线程为止。

如果您将方法作为 static synchronized :

两个调用不可能 static synchronized 同一类的不同对象的方法交织在一起。当一个线程执行 static synchronized A类的对象的方法,所有其他线程 static synchronized A类块(暂停执行)的任何对象上的方法,直到使用方法执行完成第一个线程。

您在此SE问题中找到了更好的同步替代方案:

避免在Java中同步(此)?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top