In Java5, the final keyword is very important and in fact is often overlooked as a function of synchronization. In essence, final can make the following guarantees: When you create an object, using the final keyword allows another thread to not access the "partially created" object, otherwise it can happen. This is because, when used as a property of an object, final has the following semantics:
When the constructor ends, the value of the final type is guaranteed to be visible when other threads access the object.
Why it's necessary.
One way to use final is the so-called Secure release (safe publication), where publishing (publication) means creating it in one thread, while another thread can refer to the newly created object at a later point in time. When the JVM invokes the object's constructor, it must assign each member a value and store a pointer to that object. Just like any other data write, this could be out of order, and their application to main memory can is delayed and other processors can is delayed unless you t Ake special steps to combat this (not quite understand, is not saying "write them back to main memory may be postponed, and other processors (see changes) will also be postponed, to customer service this point, unless take very steps"). In particular, a reference to an object may be preceded by a member variable submission (one of the reasons for this is that the compiler's instructions reflow ordering:if you think the How do you ' d write things in a low-level language such a s C or assembler, it ' s quite natural to store a pointer to a block of memory, and then advance the pointer as you ' re Writi Ng data to that block) is written to main memory and is accessed. This causes the other thread to see an illegal or incomplete object.
And final prevents this from happening: If a member is final, the JVM specification makes the following explicit assurance that the final member must be correctly assigned once the object reference is visible to other threads.
Final object reference
The values of the final member members of the object are also up-to-date when exiting the constructor. This means that:
The value of a member variable of the final type, including those of the collections pointed to by the final reference, is read thread-safe without the use of synchronization
Note that if you have a final reference to a collection, array, or other mutable object, you still need to use the synchronization mechanism to access the object (or use Concurrenthashmap) if there are other threads accessing it.
Therefore, immutable objects (meaning that all members are final and members are either basic types or point to another immutable object) can be accessed concurrently without using the synchronization mechanism. It is also safe to read an "actual immutable" object through a final reference (meaning that the member is not final but never changed). However, from a programming point of view, it is advisable to harden the immutability in such a case (e.g., to encapsulate a collection with collections.unmodifiablelist). That's the, you'll spot bugs introduced when one of the your colleagues naughtily attempts to modify a collection so you didn ' T intend to be modified!
Limitations and limitations of using final
When declaring a final member, you must set its value before the constructor exits, as follows:
public class MyClass { private final int myField = 3; Public MyClass () { ... }}
Or
public class MyClass { private final int myField; Public MyClass () { ... = 3; ... }}
It should be emphasized that declaring a member that points to an object as final can only make the reference immutable, not the object it refers to. For example, if a list declares the following:
Private final List myList = new ArrayList ();
You can still modify the list
Mylist.add ("Hello");
However, the statement is final to ensure that the following actions are not lawful:
MyList = new ArrayList (); myList = Someotherlist;
When should I use final?
One answer is "use as much as possible." Anything you don't want to change (the base type, or point to an object, regardless of whether the object is mutable) should generally be declared final. Another way to look at this problem is to:
If an object will be accessed in multiple threads and you do not declare its members as final, you must provide additional ways to ensure thread safety
"Other ways" can include declaring members as volatile, using synchronized or explicit lock to control access to all of that member.
The typical case that everyone tends to overlook is to create an object in one thread and then use it in another thread, such as a Threadpoolexecutor object. In this case, the thread security of the object must be guaranteed: this is not the same as the concurrent access of the thread, mainly because in its lifetime, different threads will access it at any time (or the problem with the memory model)
About final keywords and thread safety in Java