The final
modifier - while preventing the member from being re-assigned - does not affect the correctness of the given code1
From the the 17.4.4 Synchronization Order section for the Java 5 Language Specification:
A synchronization order is a total order over all of the synchronization actions of an execution .. Synchronization actions induce the synchronized-with relation on actions, defined as follows:
- ..
- An action that starts a thread synchronizes-with the first action in the thread it starts.
- ..
Then, since the thread that sets the name
member is the one that starts the thread, the synchronization order is guaranteed. (Synchronizes-with implies a Happens-before ordering.)
Note that:
- The member
name
needs only be set before starting the thread: that is, it does not need to be set in the constructor for this synchronizes-with guarantee.
- This does not guarantee synchronization ordering - and thus it does not guarantee happens-before or value visibility - between already running threads or threads created elsewhere!
However, final
fields do give a much more comfortable feeling (ref. 17.5 Final Field Semantics):
An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object *after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
In this case, with final fields, the value is guaranteed to be visible on every thread after the constructor completes. (This guarantee can be violated by "constructor leaks".)
1 In the supplied code the "non-final" name
member is only assigned once before the thread is started.
In different, less trivial, programs other synchronization issues may be exposed. This answer examines if removing final
alters the correctness of the supplied code.
All that being said, I consider it "good practice" to use both immutable variables (final
) and immutable objects - especially when dealing with threads. Instead of needing to know the little arcane details of the JVM, do the safe proven things and strive for obvious correctness over cleverness or "performance".
See also: