ConcurrentModificationException while modify unclaimed private collection from
different Threads
------------------------------------------------------------------------------------------------
Key: TAP5-1520
URL: https://issues.apache.org/jira/browse/TAP5-1520
Project: Tapestry 5
Issue Type: Bug
Components: tapestry-core
Affects Versions: 5.2.5
Reporter: Maxim Ulanovskiy
TestCase: create two parallel requests to the page bellow
first request to read action - /TestConcurrency.read
second request to write action - /TestConcurrency.write
TestConcurrency.tml:
...
<t:actionlink t:id="read">read</t:actionlink>
<t:actionlink t:id="write">write</t:actionlink>
...
public class TestConcurrency {
private List<String> testDie = new ArrayList<String>();
public void onActivate() {
for(int i=0; i<1000; i++)
testDie.add("init");
}
void onActionFromRead() {
for(String s : testDie)
System.out.println(s);
}
void onActionFromWrite() {
for(int i=0; i<100000; i++)
testDie.add("testDie"+i);
}
}
>From what I've found out with debugger is that direct access to List<String>
>testDie is replaced with UnclaimedFieldWorker.UnclaimedFieldConduit but when
>PerthreadManagerImpl is called it fails to find thread local value in
>internal map and returnes default value - the same object for both threads:
public class PerthreadManagerImpl {
<T> PerThreadValue<T> createValue(final Object key)
{
return new PerThreadValue<T>()
{
public T get()
{
return get(null);
}
public T get(T defaultValue)
{
Map map = getPerthreadMap();
// NO SUCH KEY IN map
if (map.containsKey(key))
{
Object storedValue = map.get(key);
if (storedValue == NULL_VALUE)
return null;
return (T) storedValue;
}
return defaultValue;
}
--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira