Search code examples
concurrencythread-safetysynchronizedtapestry

Should instance fields access be synchronized in a Tapestry page or component?


If a page or component class has one instance field which is a non-synchronized object, f.ex. an ArrayList, and the application has code that structurally modifies this field, should the access to this field be synchronized ?

F.ex.:

public class MyPageOrComponent
{
    @Persist
    private List<String> myList;

    void setupRender()
    {
        if (this.myList == null)
        {
            this.myList = new ArrayList<>();
        }
    }

    void afterRender(MarkupWriter writer)
    {
        // Should this be synchronized ?

        if (someCondition)
        {
            this.myList.add(something);
        }
        else
        {
            this.myList.remove(something);
        }
    }
}

I'm asking because I seem to understand that Tapestry creates only one instance of a page or component class and it uses this instance for all the connected clients (but please correct me if this is not true).


Solution

  • In short the answer is no, you don't have to because Tapestry does this for you. Tapestry will transform your pages and classes for you at runtime in such a way that wherever you interact with your fields, they will not actually be working on the instance variable but on a managed variable that is thread safe. The full inner workings are beyond me, but a brief reference to the transformation can be found here.

    One warning, don't instantiate your page/component variables at decleration. I have seen some strange behaviour around this. So don't do this:

    private List<String> myList = new ArrayList<String>;