Do we synchronize instance variables that are final? If so, what to use?

I like to know how we synchronize the instance variable, which is final. Since the variables are final, a change in value cannot be changed. Can anyone explain this?

+2
java synchronization
03 Feb 2018-10-03T00
source share
6 answers

Do we synchronize instance variables that are final?

Yes. You still need to synchronize mutable objects

final! = unchanged

public class Something { private final List list = new ArrayList(); public void add( String value ) { this.list.add( value ); } public int count() { return this.list.size(); } } 

Later

  Something s = new Something(); Thread a = new Thread() { public void run(){ s.add( "s" ); s.add( "s" ); s.add( "s" ); } }; Thread b = new Thread(){ public void run() { s.count(); s.count(); } }; a.start(); b.start(); 

If so, what to use?

You declare that this attribute cannot be changed during the lifetime of the object.

This increases security (your object attribute cannot be replaced by a malicious subclass). It allows you to optimize the compiler (since it knows that only a link will be used). It prevents subclasses from changing, etc.

An attribute that is both final and immutable (e.g. String, Integer, and others) does not require synchronization.

 class X { private final String name = "Oscar"; public int nameCount(){ return this.name.length(); //<-- Will return 5 ALWAYS ( actually the compiler might inline it } } 
+10
Feb 03 '10 at 15:07
source share

Important exception: final fields that cannot be changed after the object is created can be read safely through unsynchronized methods as soon as the object is built

Adapted from Synchronized Methods

+5
Feb 03 '10 at 15:01
source share

Usually you did not mark access methods as synchronized if the method returned the value of the final variable; eg.

 private final String message = "Hello, World"; // No need to mark as synchronized as message can never change. public String getMessage() { return message; } 

However, you can synchronize with the final variable, for example, if you used it as a lock; eg.

 private final Object lock; ... synchronized(lock) { // Do something in critical section. } 
+1
Feb 03 '10 at 15:02
source share

Well yes. When you declare a final instance variable with a reference type, that reference is immutable, but the object to which it refers is usually mutable. If there can be several threads accessing and updating the state of the object being modified, operations with the final instance must be synchronized.

For example:

 public class Thing { private final List l1 = private final List l2 = private final List l3 = ... public void l1ToL2() { l2.add(l1.removeFirst()); } public void l2ToL3() { l3.add(l2.removeFirst()); } } 

If we do not do something to synchronize the use of these methods l1 , l2 and l3 , they are not thread safe, and parallel operations from different threads can ruin the lists.

On the other hand, it is thread safe, for the reasons stated in @Anthony Forloney's answer.

 public class Thing { private final int i = ... ; public int getI() { return i; } } 
+1
03 Feb '10 at 15:05
source share

If the instance variable is not immutable, the state of this variable can be changed, even if it is final. Take for example:

 private final List<Foo> foos = new ArrayList<Foo>(); public void addFoo(Foo newFoo){ foos.add(newFoo); } public Foo popFoo(){ return foos.remove(0); } 

In this situation, even if foos is final, a Foo can be added to Thread B, while Thread A tries to remove the element, which leads to a potentially compatible state.

The tutorial on synchronized methods, mentioned in other examples, is true that reading the final variable does not need to be synchronized. However, if the variable is changed (as List<T> is), then the record in this variable must be synchronized to guarantee the connection "will happen sooner". If, however, the variable is unchanged, then, of course, records are still not allowed on this variable, so there is no need to synchronize.

+1
Feb 03 2018-10-15T00
source share

There is no need to synchronize access to the latest instance variables.

see http://java.sun.com/docs/books/tutorial/essential/concurrency/syncmeth.html

Synchronized methods allow a simple strategy to prevent thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to these object variables are performed using synchronized methods. (Important exception: final fields that cannot be changed after the creation of the object can be safely read using unsynchronized methods after the creation of the object). This strategy is effective, but it may pose problems with viability, as we will see later in this lesson.

0
03 feb. '10 at 15:02
source share



All Articles