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

发布于 2024-08-31 02:25:04 字数 117 浏览 3 评论 0原文

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

如果可以的话,请用一个例子来让它更清楚。

What is the difference between synchronized methods and synchronized statements?

If possible, please use an example to make it more clear.

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

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

发布评论

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

评论(5

迷雾森÷林ヴ 2024-09-07 02:25:04

同步方法会锁定与类实例(即“this”)或类(如果是静态方法)关联的监视器,并阻止其他人这样做,直到从该方法返回为止。同步块可以锁定任何监视器(您告诉它哪个),并且可以具有比封闭方法更小的范围。

如果同步块最终不等于方法的整个范围,和/或如果它们锁定的东西比实例(或类,如果是静态的)不那么严格,则首选同步块。

A synchronized method locks the monitor associated with the class instance (ie 'this') or the class (if a static method), and prevents others from doing so until the return from the method. A synchronized block can lock any monitor (you tell it which) and can have a scope smaller than that of the enclosing method.

Synchronized blocks are preferred if they don't end up equivalent to the entire scope of the method, and/or if they lock something less draconian than the instance (or class if static).

小梨窩很甜 2024-09-07 02:25:04

引自 JLS(包括示例):

JLS 14.19 同步声明

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

JLS 8.4.3.6 <代码>同步方法

synchronized 方法在执行之前获取监视器。对于类(静态)方法,将使用与该方法的类的Class 对象关联的监视器。对于实例方法,使用与 this(调用该方法的对象)关联的监视器。

这些锁与 synchronized 语句可以使用的锁相同;因此,代码:

类测试{
    整数计数;
    同步无效碰撞(){计数++; }
    静态 int 类计数;
    静态同步无效 classBump() {
        类计数++;
    }
}

与以下效果完全相同:

类 BumpTest {
    整数计数;
    无效凹凸(){
        同步(这个){
            计数++;
        }
    }
    静态 int 类计数;
    静态无效类Bump(){
        尝试 {
            同步(Class.forName(“BumpTest”)){
                类计数++;
            }
        } catch (ClassNotFoundException e) {
                ...
        }
    }
}

那么它们有何不同?

引自Effective Java 2nd Edition,第 67 项:避免过度同步:

通常,您应该在同步区域内做尽可能少的工作。

方法的 synchronized 修饰符作为一种语法糖,适用于许多但并非所有场景。本书更深入地讨论了为什么应该避免过度同步,但基本上通过使用同步语句,您可以更好地控制同步区域的边界(如果场景需要,也可以选择自己的锁)。

除非您的方法非常简单和/或您需要在方法的整个持续时间内获取 this 锁(或者如果方法是 则获取 Class 对象锁) static),您应该使用 synchronized 语句将方法内的同步限制为仅在您需要时(即,当您访问共享可变数据时)。

Quotes from the JLS (including example):

JLS 14.19 The synchronized Statement

A synchronized statement acquires a mutual-exclusion lock on behalf of the executing thread, executes a block, then releases the lock. While the executing thread owns the lock, no other thread may acquire the lock.

JLS 8.4.3.6 synchronized Methods

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) {
                ...
        }
    }
}

So how are they different?

A quotes from Effective Java 2nd Edition, Item 67: Avoid excessive synchronization:

As a rule, you should do as little work as possible inside synchronized regions.

The synchronized modifier for methods, being a syntactic sugar that it is, is applicable in many but not all scenarios. The book goes to discuss in much deeper detail why you should avoid excessive synchronization, but basically by using synchronized statements, you have much greater control over the boundaries of your synchronized regions (and if the scenario requires it, you can also choose your own locks).

Unless your method is very simple and/or you need to acquire the this lock for the entire duration of the method (or the Class object lock if the method is static), you should use synchronized statements to limit the synchronization within the method to only to when you need it (i.e. when you're accessing shared mutable data).

暮年慕年 2024-09-07 02:25:04

synchronized 方法是其主体自动封装在 synchronized 块中的方法。

因此,这是相等的:

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

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

A synchronized method is a method whose body is encapsulated automatically in a synchronized block.

Thus, this is equal:

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

public synchronized void foo()
{
    bar();
}
冰葑 2024-09-07 02:25:04

synchronized on 方法锁定在 this 对象上。它等于 synchronized (this) {}

标准 synchronized 锁定在指定的对象/监视器上。通过synchronized (***) {},您可以选择用于锁定的对象。

synchronized on method is locked on a this object. It's equals to synchronized (this) {}

Standard synchronized is locked on specified object/monitor. With synchronized (***) {} you can choose an object to use for locking.

可爱咩 2024-09-07 02:25:04

实际上,同步方法是一种将函数的​​整个主体放置在同步块中的方法。同步块的优点是您可以将同步块仅应用于函数中的几个 select 语句,而不是应用于整个函数。一般来说,最好使同步块尽可能短,因为花费在同步块中的时间可能会阻止其他线程执行有意义的工作。另一个区别是,在使用同步块时,您可以指定要应用锁的特定对象,而使用同步方法时,对象本身会自动用作执行同步的锁。

A synchronized method is one where you have, in effect, placed the entire body of the function in a synchronized block. A synchronized block has the advantage that you can apply the synchronized block to just a few select statements in the function, instead of to the function as a whole. In general, it is best to make synchronized blocks as short as possible, since time spent in synchronized blocks is time that some other thread might be prevented from doing meaningful work. Another distinction is that you can specify a particular object on which to apply the lock when using a synchronized block whereas with a synchronized method, the object, itself is automatically used as the lock on which synchronization is performed.

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