java - 为什么需要为synchronized语句指定锁?

标签 java concurrency synchronized

鉴于类的每个实例只有一把锁,那么为什么 Java 不允许我们这样做:

void method() {
    synchronized {
        // do something
    }

    // do other things
}

而不是这个:

void method() {
    synchronized (lock) {
        // do something
    }

    // do other things
}

指定锁的目的是什么?如果我选择一个对象作为另一个对象的锁,会有什么不同吗?或者我可以选择任何随机对象吗?

编辑:

事实证明,我对同步方法的理解在根本上是错误的。

我认为不同的同步方法或 block 是完全相互独立的,无论锁如何。相反,具有相同锁的所有同步方法或 block 只能由一个线程访问,即使此类同步方法/ block 来自不同的类(文档应该更加强调这一点:所有同步方法/ block ,无论位置如何,重要的是锁)。

最佳答案

Given that there's only one lock for each instance of a class, then why doesn't Java just allow us to do this:

void method() {
    synchronized {
        // do something
    }

    // do other things
}

虽然每个实例都提供了内在锁, 这不一定是要使用的“明显”锁。

您可能是对的,他们可以提供 synchronized { ... } 作为 synchronized (this) { ... } 的简写。 我不知道他们为什么不这样做,但我从来没有错过过。 但并发编程很棘手, 因此,将锁对象设置为显式必需参数可能会让读者更清楚,这是一件好事,正如 @ajb 在评论中指出的那样。 无论如何,我认为语法不是您的主要问题,所以让我们继续。

What's the purpose of specifying a lock?

嗯,锁可能是同步机制中最重要的事情。同步的关键点是只有一个线程可以持有同一个锁。持有不同锁的两个线程不同步。因此,了解保护同步的锁是什么至关重要。

Does it make a difference if I choose one object as a lock over the other?

我希望上一节已经清楚地表明,是的,你必须仔细选择对象。它必须是所有涉及的线程都可见的对象, 它必须不为空,并且必须是在同步期间不会被重新分配的内容。

Or could I just choose any random object?

当然不是。请参阅上一节。

要了解 Java 中的并发性,我推荐这本书 Java Concurrency in Practice由 API 的作者之一编写,或 Oracle's tutorials就这个主题而言。

关于java - 为什么需要为synchronized语句指定锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41296513/

相关文章:

java - 带有文件名的子类中出现奇怪的错误

java - Android opencv加载16位深度的灰度png

java - 消除读取和写入数据时sql server 2008的死锁问题

java - 当java不应该分割字符串时,我可以给Java一个正则表达式吗?

c++ - 这是线程安全 Queue 类的正确方法吗?

java - Java中这些短方法必须同步吗?

multithreading - 并发插入和更新 postgres

java - "private"修饰符是否也确保Java中的线程安全

java - 为什么使用原子变量访问比通过同步代码访问这些变量更有效?

java - java中无法同步方法