July 27, 2016
While testing vmlens, a tool to find data races in java applications, on open source projects, I found the following 5 tricks how to make classes thread safe.
private FieldAccessor fieldAccessor; private FieldAccessor getFieldAccessor(Object obj) throws IllegalAccessException { boolean ov = override; FieldAccessor a = (ov) ? overrideFieldAccessor : fieldAccessor; return (a != null) ? a : acquireFieldAccessor(ov); }
Since it is not synchronized and not declared volatile, a thread reading this field might not see a completely initialized object as described in DoubleCheckedLocking But since the created object type sun.reflect.UnsafeQualifiedIntegerFieldAccessorImpl only uses final problem, there is no problem. Threads reading this field will always see a fully initialized object or null.
Take for example the old version from org.apache.commons.lang.StringEscapeUtils. It uses the lazy initialized class org.apache.commons.lang.Entities$LookupEntityMap:
private String[] lookupTable() { if (lookupTable == null) { createLookupTable(); } return lookupTable; }
This only works with locks or synchronization. Much better is the new version org.apache.commons.lang3.StringEscapeUtils witch eagerly creates the lookup tables and also uses a final field.
public static final CharSequenceTranslator ESCAPE_XML10 = new AggregateTranslator( ...
private volatile boolean isWorking; while(isWorking) { // do something }Use a volatile field to make the changes done in one thread visible in other threads.
© 2020 vmlens Legal Notice Privacy Policy