鉴于类的每个实例只有一把锁,那么为什么 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/