Java 为什么“synchronized”对于变量是非法的?
这是一个非常简单的问题,但我无法理解其背后的想法: 为什么Java 为什么“synchronized”对于变量是非法的?,java,variables,synchronized,Java,Variables,Synchronized,这是一个非常简单的问题,但我无法理解其背后的想法: 为什么synchronized不能分配给Java变量 它只能指定给方法和块。 我个人认为这对Java编程语言来说是一个非常好的补充。他们有这个关键词。对你没有帮助。您可以使用synchronized使代码块成为原子代码。因此,在大多数情况下,需要同步的代码行不止一行。同步的代码块保护完整的代码块。方法上的同步保护方法的完整代码。在这两种情况下,synchronized指的是它用作监视器的对象—this(或当前类对象)或指定的对象 第一:对监视器
synchronized
不能分配给Java变量
它只能指定给方法和块。
我个人认为这对Java编程语言来说是一个非常好的补充。他们有这个关键词。对你没有帮助。您可以使用synchronized使代码块成为原子代码。因此,在大多数情况下,需要同步的代码行不止一行。同步的代码块保护完整的代码块。方法上的同步保护方法的完整代码。在这两种情况下,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
调用本身不受保护
哦,我忘了:在这两种情况下,您只能使用synchronized的互斥功能,wait
或notify
功能将不可用,因为您无法将任何代码附加到变量
剩下的是:
也许只是原子参考的快捷方式
这是一个非常罕见的用例,因此更改语言本身不是一个好的选择。如果您正在寻找原子行为的字段,请尝试
java.util.concurrent.atomic
类。例如,AtomicInteger
允许您以原子方式向其添加数字。如果对象分配是一个问题,并且您确定自己需要它,AtomicIntegerFieldDupDater
(及其同类产品)可以让您像原子一样访问volatile
字段,但您必须小心,因为使用这种方法很容易破坏代码。在变量上设置时,您希望它实际做什么?您应该将对字段的访问包装为(可能是同步的)getter和setter,对吗?;-)wjat您希望通过synchronized
实现什么?而且synchronized
确实需要一个对象(监视器)@JoachimIsaksson轻松自动原子访问。:)@Michael,定义原子的
,b/c我想你实际上并不是指原子的
,我想你经常只是想访问一个变量原子的。@Michael:有原子引用或volatile
关键字。@Michael,除非32位上的long/double
,否则所有变量都是原子变量,您希望处理一个变量,但要处理多行代码。因此,您必须同步整个代码块。否则,您可能会遇到与其他线程的争用情况。@bestsss:atomic,因为在其他线程中无法看到“半写值”。但这并不意味着其他线程可以看到更改。但不涉及监视器,尽管我想另一种选择是,如果sb
是同步的
,那么使用它的任何方法都会在整个方法块的sb
上隐式同步。因此,在您的示例中,doSomething2()
相当于doSomething2(){synchronized(sb){this.sb.append(“foo”);}
。将该想法归档到“实现死锁的非常非常简单的方法”下。@yshavit:您的想法的一个注释:由于sb
是公共的,这意味着从另一个类访问sb
将需要该另一个类中的额外代码。现在想象一下,我们的sb
类发生了变化:它添加或删除了synchronize
,但第二个类没有重新编译。。。这是对封装的又一次打击。是的,但是您可以说synchronized
-包装只发生在声明成员的类中。这将允许其他类破坏您的原子性,但这就是提供需要同步访问的引用所得到的结果。如果你有公共StringBuidler sb;私有最终对象锁=新对象()
具有一个不变量,sb
总是在同步(锁)
中访问。顺便说一句,另一个可能(但不是很有帮助)的选择是让同步sb
意味着任何使用sb
的方法(在类中)都是在上同步的。但是今天已经结束了,我在等公共汽车。:)@伊莎维特:我明白,我不想变得粗鲁或诸如此类。你的想法是正确的。我只是想探索一些含义。希望你能赶上公共汽车:-)