I'm beginning to think that we should simply check that the
initialization of any field is an immutable value; we know what main
JDK classes are immutable (String, Boolean, Number) and can have a
service (combined with an @Immutable annotation) go further.

This is a recurring question on the list, but not one that fits into
an FAQ meaningfully ... I think the framework needs to change.

On Thu, May 5, 2011 at 5:35 AM, Thiago H. de Paula Figueiredo (JIRA)
<[email protected]> wrote:
>
>     [ 
> https://issues.apache.org/jira/browse/TAP5-1520?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
>  ]
>
> Thiago H. de Paula Figueiredo closed TAP5-1520.
> -----------------------------------------------
>
>    Resolution: Invalid
>
> Hi!
>
> The error here is in your code: you should never initialize a field with a 
> non-atomic value. An event handler like onActivate(), @BeginRender or some 
> event triggered by Form.
>
> Please post in the user mailing list before posting bugs.
>
> Cheers!
>
> Thiago
>
>> 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
>



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to