我们是否同步最终的实例变量?如果是的话有什么用?
我想知道我们是否同步最终的实例变量。由于变量是最终变量,因此值不能更改。 有人能解释一下吗?
I like to know do we synchronize the instance variable which are final. As variables are final there can not be change in the value.
Can anybody explain this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
是的。你还是要同步可变对象
final != immutable
稍后
您声明,给定的属性在对象生命周期内不能更改。
这提高了安全性(您的对象属性不能被恶意子类替换)
允许编译器优化(因为它知道只会使用引用)
防止子类更改它等等。
既是最终属性又是不可变属性(如字符串、整数等)不需要同步。
Yes. You still have to synchronize mutable objects
final != immutable
Later
You're declaring, that a given attribute can't be changed during the object life time.
This increases the security ( your object attribute can't be replaced by a malicious subclass )
Allows compiler optimizations ( because it knows that only a reference will be used ever )
Prevents subclasses from changing it and so on.
An attribute that is both, final and immutable ( like String, Integer and others ) doesn't need synchronization.
取自 同步方法
Taken from Synchronized Methods
如果访问器方法返回最终变量的值,您通常不会将其标记为“同步”;例如,
但是,您可能希望同步最终变量,例如,如果您将其用作锁;例如
You typically would not mark accessor methods as
synchronized
if the method was returning the value of a final variable; e.g.However, you may wish to synchronize on the final variable, for example if you were using it as a lock; e.g.
如果实例变量不是不可变的,那么即使该变量是最终变量,其状态仍然可以更改。举个例子:
在这种情况下,即使
foos
是最终的,当线程 A 尝试删除元素时,线程 B 也可以添加Foo
,这可能会导致一致状态。其他示例中提到的同步方法教程是正确的,因为读取最终变量不需要同步。但是,如果变量是可变的(如
List
那样),则必须同步对该变量的写入,以保证“发生之前”关系。但是,如果变量是不可变的,那么当然不允许对该变量进行写入,因此不需要同步。If the instance variable isn't immutable, then the state of that variable can still be changed even if it is final. Take, for example:
In this situation, even though
foos
is final, aFoo
can be added by Thread B while Thread A is attempting to remove an element, leading to potentially iconsistent state.The Sychronized Methods tutorial mentioned in other examples is correct in that reading a final variable does not need to be sychronized. However, if the variable is mutable(as
List<T>
is), then writing to that variable must be synchronized to guarantee a "happens-before" relationship. If, however, the variable is immutable, then of course writes are not allowed to that variable anyway, so there is no need to synchronize.嗯,是的。当您使用引用类型声明最终实例变量时,该引用是不可变的,但它引用的对象通常是可变的。如果可能有多个线程访问和更新可变对象的状态,则需要同步对最终实例的操作。
例如:
如果我们不采取措施来同步这些方法对
l1
、l2
和l3
的使用,那么它们就不是线程安全的,并且来自不同线程的并发操作可能会损坏列表。另一方面,由于 @Anthony Forloney 的回答中所述的原因,这是线程安全的。
Well yes. When you declare a final instance variable with a reference type, the reference is immutable but the object it refers to typically is mutable. If there may be multiple threads accessing and updating the state of mutable object, the operations on the final instance need to be synchronized.
For example:
If we don't do something to synchronize those methods' use of
l1
,l2
andl3
, they are not thread-safe, and concurrent operations from different threads could corrupt the lists.On the other hand, this is thread-safe, for the reasons stated in @Anthony Forloney's answer.
无需同步对最终实例变量的访问。
请参阅 http://java.sun.com/docs/books /tutorial/essential/concurrency/syncmeth.html
同步方法启用了一种防止线程干扰和内存一致性错误的简单策略:如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都会完成通过同步方法。 (一个重要的例外:final 字段在对象构造后无法修改,一旦构造了对象,就可以通过非同步方法安全地读取)这种策略是有效的,但可能会带来活性问题,因为我们将请参阅本课稍后内容。
There is no need to synchronize access to final instance variables.
see http://java.sun.com/docs/books/tutorial/essential/concurrency/syncmeth.html
Synchronized methods enable a simple strategy for preventing thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to that object's variables are done through synchronized methods. (An important exception: final fields, which cannot be modified after the object is constructed, can be safely read through non-synchronized methods, once the object is constructed) This strategy is effective, but can present problems with liveness, as we'll see later in this lesson.