Search code examples
javajava-ee-6

Should a @Singleton bean return an internal List<> member?


This is possibly a really easy question, but it's something that's not entirely clear to me.

I have a bean as follows:

@Singleton
@Startup
@Lock(READ)
public class SomeDataBean {
  List<Foo> foos;

  @PostConstruct
  public void init() {
    // Build foos;
  }

  public List<Foo> getFoos() {
    return foos;
  }

  @Lock(WRITE)
  public void modifyFoos() {
    // This could be potentially called too
  }
}

Subsequently, this bean is injected (using CDI - environment is Wildfly 8.2), into various other beans (Request/Session/View etc.) Now they all access this list of Foos. My question is, is it safe to return the list as is, when potentially modifyFoos() could be invoked by another bean. Or is this something that will never happen and is guaranteed by the container?

I've read some of the docs on the container managed transactions etc, but it's not entirely clear how it works in situations such as this. Is it better here to replace list with a concurrent container for example?


Solution

  • No, it is not safe, because a thread can read the list while another thread modifies it.

    1. Return a copy of the list (not efficient if there are many reads).
    2. Use copy-on-write list.
    3. Store a new instance of the list in modifyFoos.