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

发布于 2024-07-27 20:16:31 字数 143 浏览 3 评论 0原文

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

我一直在网上搜索答案,人们似乎对此非常不确定:-(

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

如果对静态方法加锁,那么对类加锁的含义是什么?

What is the difference between a synchronized method and synchronized block in Java ?

I have been searching the answer on the Net, people seem to be so unsure about this one :-(

My take would be there is no difference between the two, except that the synch block might be more localized in scope and hence the lock will be of lesser time ??

And in case of Lock on a static method, on what is the Lock taken ? What is the meaning of a Lock on Class ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

貪欢 2024-08-03 20:16:31

同步方法使用方法接收器作为锁(即非静态方法的 this 和静态方法的封闭类)。 Synchronized 块使用表达式作为锁。

因此,从锁定的角度来看,以下两种方法是等效的:

synchronized void mymethod() { ... }

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

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

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

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

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

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

锁定范围< /b>

对于同步方法,锁将在整个方法范围内保持,而在 synchronized 块中,锁仅在该块范围内(也称为临界区)保持。 在实践中,如果 JVM 能够证明可以安全地完成,则允许通过从同步块执行中删除一些操作来进行优化。

A synchronized method uses the method receiver as a lock (i.e. this for non static methods, and the enclosing class for static methods). Synchronized blocks uses the expression as a lock.

So the following two methods are equivalent from locking prospective:

synchronized void mymethod() { ... }

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

For static methods, the class will be locked:

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

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

For synchronized blocks, you can use any non-null object as a lock:

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

Lock scope

For synchronized methods, the lock will be held throughout the method scope, while in the synchronized block, the lock is held only during that block scope (otherwise known as critical section). In practice, the JVM is permitted to optimize by removing some operations out of the synchronized block execution if it can prove that it can be done safely.

碍人泪离人颜 2024-08-03 20:16:31

同步方法是简写。 从所有意图和目的来看,这

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 的类对象。)

确实如此,使用同步块,您可以更具体地了解您的锁,并更详细地了解何时要使用它,但除此之外没有任何区别。

A synchronized method is shorthand. This:

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

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

is, for all intents and purposes, equivalent to this:

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

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

(Where Something.class is the class object for the class Something.)

So indeed, with a synchronized block, you can be more specific about your lock, and more fine-grained about when you want to use it, but other than that there's no difference.

残疾 2024-08-03 20:16:31

是的,这是一个区别。 另一个是您可以获取除 this 之外的其他对象的锁。

Yes, that is one difference. The other is that you can acquire a lock on other objects than this.

幸福%小乖 2024-08-03 20:16:31

关键区别在于:如果您声明一个方法要同步,那么该方法的整个主体都会变为同步; 但是,如果使用同步块,则可以仅将方法的“关键部分”包围在同步块中,而将方法的其余部分保留在块之外。

如果整个方法是关键部分的一部分,那么实际上没有区别。 如果情况并非如此,那么您应该仅在关键部分周围使用同步块。 同步块中的语句越多,获得的整体并行性就越少,因此您希望将这些语句保持在最低限度。

The key difference is this: if you declare a method to be synchronized, then the entire body of the method becomes synchronized; if you use the synchronized block, however, then you can surround just the "critical section" of the method in the synchronized block, while leaving the rest of the method out of the block.

If the entire method is part of the critical section, then there effectively is no difference. If that is not the case, then you should use a synchronized block around just the critical section. The more statements you have in a synchronized block, the less overall parallelism you get, so you want to keep those to the minimum.

安人多梦 2024-08-03 20:16:31

同步方法锁定该方法所在的对象实例。

同步块可以锁定任何对象 - 通常是定义为实例变量的互斥对象。 这可以更好地控制正在运行的锁。

A synchronized method locks on the object instance the method is contained in.

Where as a synchronized block can lock on ANY object - typically a mutex obect defined as an instance variable. This allows more control over what locks are in operation.

夜夜流光相皎洁 2024-08-03 20:16:31

我的看法是,两者之间没有区别,只是同步块的范围可能更本地化,因此锁定的时间会更短??

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

java 教程中的示例:

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

同步语句对于通过细粒度同步提高并发性也很有用。 您可以在同一教程页面上找到以下用例的好示例。

例如,假设类 MsLunch 有两个实例字段 c1 和 c2,它们从不一起使用。 这些字段的所有更新都必须同步,但是没有理由阻止 c1 的更新与 c2 的更新交错 — 这样做会通过创建不必要的阻塞来减少并发性。 我们不使用同步方法或以其他方式使用与此相关的锁,而是创建两个对象来提供锁

如果对静态方法进行锁定,那么锁定的对象是什么? 类锁定是什么意思?

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

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

同一对象上的两次同步方法调用不可能交错。 当一个线程正在执行对象的同步方法时,调用同一对象的同步方法的所有其他线程都会阻塞(挂起执行),直到第一个线程完成该对象。

如果将方法设置为静态同步方法:

同一类的不同对象上的静态同步方法的两次调用不可能交错。 当一个线程正在为 A 类对象执行静态同步方法时,所有其他对 A 类对象调用静态同步方法的线程都会阻塞(暂停执行)直到第一个线程完成方法执行。

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

避免在Java中同步(this)?< /a>

My take would be there is no difference between the two, except that the synch block might be more localized in scope and hence the lock will be of lesser time ??

Yes. You are right. Unlike synchronized methods, synchronized statements must specify the object that provides the intrinsic lock.

Example from java tutorial:

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

Synchronized statements are also useful for improving concurrency with fine-grained synchronization. You can find good example on same tutorial page for below use case.

Suppose, for example, class MsLunch has two instance fields, c1 and c2, that are never used together. All updates of these fields must be synchronized, but there's no reason to prevent an update of c1 from being interleaved with an update of c2 — and doing so reduces concurrency by creating unnecessary blocking. Instead of using synchronized methods or otherwise using the lock associated with this, we create two objects solely to provide locks.

And in case of Lock on a static method, on what is the Lock taken ? What is the meaning of a Lock on Class ?

In this case, the thread acquires the intrinsic lock for the Class object associated with the class. Thus access to class's static fields is controlled by a lock that's distinct from the lock for any instance of the class.

When you make a method as synchronized ( non static ) :

It is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

If you make a method as static synchronized :

It is not possible for two invocations of static synchronized methods on different objects of same class to interleave. When one thread is executing a static synchronized method for an object of Class A, all other threads that invoke static synchronized methods on any of objects of Class A block (suspend execution) until the first thread is done with the method execution.

You find better alternatives to synchronization in this SE question:

Avoid synchronized(this) in Java?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文