为什么“synchronized”对于变量来说是非法的?

发布于 2025-01-05 07:36:15 字数 161 浏览 6 评论 0原文

这是一个非常简单的问题,但我无法理解其背后的想法:

为什么synchronized不能赋值给Java变量?

它只能分配给方法和块。 我个人认为这将是对 Java 编程语言的一个非常巧妙的补充。

It is a very easy question but I cant get the idea behind it:

Why synchronized cannot be assigned to Java variables?

It can be assigned to methods and blocks, only.
I personally think this would be a very neat addition to the Java programming language.

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

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

发布评论

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

评论(4

风和你 2025-01-12 07:36:15

同步块保护完整的代码块。方法上的同步可以保护该方法的完整代码。在这两种情况下,synchronized 指的是它用作监视器的对象 - this (或当前类对象)或指定的对象。

第一:对监视器对象的要求意味着同步字段不能是原始类型。

第二:字段上的同步应该做什么?

有两个可能的答案:

  • 保护对引用本身的访问 XOR
  • 保护对引用后面的对象的访问。

选项一是先有鸡还是先有蛋的问题:为了保护访问,必须首先访问该字段。尝试在多处理器上以原子方式执行此操作可能会很有趣。此外:如果访问是写入(即对象更改),那么监视器将在第一个对象上,而安装第二个对象......疯狂就在这条路上。

选项二:请参阅这段代码:

public class Foo {
     public synchronized StringBuilder sb = ...;
     public void doSomething1(){
         StringBuilder sb = this.sb;
         sb.append("foo");
     }

     public void doSomething2(){
         this.sb.append("foo");
     }
}

由于只有访问受到保护,因此两种方法的作用相同。第一个版本只是让它更清楚一点,即 append 调用本身不受保护。

哦,我忘了:在这两种情况下,您只能使用同步的互斥 - waitnotify 内容将不可用 - 因为您无法将任何代码附加到变量。

剩下的是什么:

也许只是 AtomicReference 的快捷方式?

这是一个非常罕见的用例,更改语言本身并不是一个好的选择。

A synchronized block protects the complete code block. A synchronized on a method protects the complete code of the method. In both cases synchronized refers to an object it uses as the monitor - either this (or the current class object) or the specified object.

First: The requirement for a monitor object means that a synchronized field could not be a primitive type.

Second: What should a synchronized on a field do?

There are two possible answers:

  • protect access to the reference itself XOR
  • protect access to the object behind the reference.

Option one would be a hen-egg problem: In order to protect the access the field must be first accessed. Try to do this atomically on a multiprocessor might be fun. Furthermore: If the access is a write (i.e. the object changes) then the monitor would be on the first object while the second one is installed ... madness is on this road.

Option two: See this piece of code:

public class Foo {
     public synchronized StringBuilder sb = ...;
     public void doSomething1(){
         StringBuilder sb = this.sb;
         sb.append("foo");
     }

     public void doSomething2(){
         this.sb.append("foo");
     }
}

Since only the access would be protected, both methods do the same. The first version just makes it a little clearer, that the append call itself is not protected.

Oh, I forgot: In both cases you could use only the mutual exclusion of synchronized - the wait or notify stuff would be unavailable - because you cannot attach any piece of code to the variable.

What is left:

Perhaps just a shortcut for AtomicReference?

This is such a rare usecase, that changing the language itself is not a good option.

听你说爱我 2025-01-12 07:36:15

他们有 volatile 关键字。

they have the volatile keyword for that.

☆獨立☆ 2025-01-12 07:36:15

不会帮助你。您使用synchronized 使代码块成为原子的。因此,大多数时候,您想要同步的代码不止一行。

Wouldn't help you. You use synchronized to make a block of code atomic. So most of the time, you have more than one line of code you want to synchronize.

迷爱 2025-01-12 07:36:15

如果您正在寻找以原子方式操作的字段,请尝试使用 java.util.concurrent.atomic 类。例如,AtomicInteger 允许您自动向其中添加数字。如果对象分配是一个问题并且您确定需要它,AtomicIntegerFieldUpdater(及其同类)可以为您提供对易失性字段的原子式访问 -但你必须小心,因为用这种方法很容易破坏你的代码。

If you're looking for fields that act atomically, try the java.util.concurrent.atomic classes. For instance, an AtomicInteger lets you add numbers to it atomically. If object allocation is a concern and you're sure you need it, AtomicIntegerFieldUpdater<T> (and its ilk) can give you atomic-like access to volatile fields -- but you have to be careful with that, because it's easy to break your code with that approach.

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