java final 与 线程安全(Thread-safety)
Thread-safety with the Java final keyword
来源于:http://www.javamex.com/tutorials/synchronization_final.shtml
?
As of Java 5, the final keyword is a very important and often overlooked(漏看,忽略) weapon in yourconcurrency armoury(军械库;武器厂). Essentially, final can be used to make sure that when youconstruct an object, another thread accessing that object doesn't see that objectin a partially-constructed state, as could otherwise happen.This is because when used as an attribute on the variables of an object, finalhas the following important characteristic as part of its definition:
?
before the fields themselves have been committed(this can happen partly because of compiler ordering:if you think about how you'd write things in a low-level language such asC or assembler, it's quite natural to store a pointer to a block of memory, and then advancethe pointer as you're writing data to that block).And this in turn could lead to anotherthread seeing the object in an invalid or partially constructed state.?
final prevents this from happening:if a field is final, it is part of the JVM specification that it must effectively ensurethat, once the object pointer is available to other threads, so are the correct valuesof that object's final fields.
?
Final object referencesThe fields on any object accessed via a final reference are alsoguaranteed to be at least as up to date(最新的,最近的) as when the constructor exits. This means that:
final reference. However, from a program designperspective, you'd be wise to try and enforce immutability in this case (e.g. bywrapping a collection in a Collections.unmodifiableList()1 etc). That way, you'llspot bugs introduced when one of your colleagues naughtily attempts to modify a collection that you didn'tintend to be modified!Restrictions and limitations of using finalWhen you declare a field final, you must set the value onceby the time the constructor exits. This means that you can declare afinal field as follows:
?
If your object is accessed by multiple threads, and you don't declare its fields final, then you must provide thread-safety by some other means.?
Other means could include declaring the field volatile,using synchronized oran explicit Lock around all accesses to that field.
A typical case that people overlook is where an object is created by one threadand then later consumed by another thread, e.g. an object via aThreadPoolExecutor.In this case, the object must still bemade properly thread-safe: it doesn't matter that the accesses by different threads aren'tconcurrent. What matters is that the object is accessed by different threads atany point in its lifetime.
?
?