Description
My name is Yu Lin. I'm a Ph.D. student in the CS department at
UIUC. I'm currently doing research on mining Java concurrent library
misusages. I found some misusages of ConcurrentHashMap in Struts
2.3.4, which may result in potential atomicity violation bugs or harm
the performance.
The code below is a snapshot of the code in file
core/src/main/java/org/apache/struts2/components/UIBean.java from line
1227 to 1244
L1227 Set<String> standardAttributes = standardAttributesMap.get(clz);
L1228 if (standardAttributes == null)
In the code above, an atomicity violation may occur between lines
<1228 and 1230>. Suppose a thread T1 executes line 1227 and finds out
the concurrent hashmap "standardAttributes" dose not contain the key
"clz". Before it gets to execute line 1230, another thread T2 puts a
pair <clz, v> in the concurrent hashmap "standardAttributes". Now
thread T1 resumes execution and it will overwrite the value written by
thread T2. Thus, the code no longer preserves the "put-if-absent"
semantics.
I found some similar misusages in other files:
In
xwork-core/src/main/java/com/opensymphony/xwork2/ognl/OgnlUtil.java,
there are similar atomicity violations as the above code at lines 242
and 415. Note that if we change "beanInfoCache.put" to
"beanInfoCache.putIfAbsent" at line 415, the synchronized key word on
"beanInfoCache" can be removed so that the performance can be improved.
Similarly, in
xwork-core/src/main/java/com/opensymphony/xwork2/util/LocalizedTextUtil.java,
atomicity violations may occur at line 254, 263 and 707 (thread T2 may
put a pair <key, value> into the map before thread T1 puts). Second,
before thread T1 executes line 257 or 266, thread T2 may remove the
key "key" from concurrent hashmap "bundlesMap". Thus, after T1 resumes
execution, it will get null value at line 257 or 266, which is also an
atomicity violation.