This discussion is archived
8 Replies Latest reply: Mar 5, 2010 7:23 AM by jduprez RSS

Are static nested classes thread-safe?

843853 Newbie
Currently Being Moderated
There doesn't seem to be any definitive answer to this. Given the following code, is it thread-safe?
public class SomeMultiThreadedWebController {

public HttpServletResponse someMethodToExecuteViaWebRequest(HttpServletRequest request) {
    simpleQueryBuilder("SELECT...").addParameter("asdf","asdf").createQuery(EMF.getEntityManager()).executeUpdate();
}

protected static class SimpleQueryBuilder {
         
         private String queryString;
         private Map<String, Object> params = new HashMap<String, Object>();
         
         public SimpleQueryBuilder(String queryString) {
              this.queryString = queryString;
         }
         
         public SimpleQueryBuilder addParameter(String name, Object value) {
              params.put(name, value);
              return this;
         }
         
         public Query createQuery(EntityManager em) {
              Query query = em.createQuery(queryString);
              for (Entry<String, Object> entry : params.entrySet()) {
                   query.setParameter(entry.getKey(), entry.getValue());
              }
              return query;
         }
    }
    
    public static SimpleQueryBuilder simpleQueryBuilder(String queryString) {
         return new SimpleQueryBuilder(queryString);
    }
}
Forget whether or not someone would do this, as this is just an example. I'm really trying to get at whether or not the instance variables inside the static nested class are thread-safe. Thanks for any responses.
  • 1. Re: Are static nested classes thread-safe?
    jduprez Pro
    Currently Being Moderated
    I'm not sure the notion that a variable is thread-safe means something. I would merely use "this usage of <variable> is thread-safe" or "all usages of ... are thread safe". Such a statement would have very little to do with how the variable is defined and much more with how the defining class enforces proper concurrent acces to the variable.
    There doesn't seem to be any definitive answer to this.
    I think there are formal and definitive answers to most of such questions in the JLS . It's an involved read though, especially the thread-safety parts :o)
    public HttpServletResponse someMethodToExecuteViaWebRequest(HttpServletRequest request) {
    simpleQueryBuilder("SELECT...").addParameter("asdf","asdf").createQuery(EMF.getEntityManager()).executeUpdate();
    }
    
    public static SimpleQueryBuilder simpleQueryBuilder(String queryString) {
    return new SimpleQueryBuilder(queryString);
    }
    whether or not the instance variables inside the static nested class are thread-safe. Thanks for any responses.
    Each invocation to someMethodToExecuteViaWebRequest(...) creates a new instance of SimpleQueryBuilder, to which, from what you expose, no reference escapes the method. So no other thread than the current one could see this instance, and its variables.
    So yes, this code is "thread-safe", or merely, this code does ot incurr concurrent access to any of SimpleQueryBuilder's instance members.
  • 2. Re: Are static nested classes thread-safe?
    843853 Newbie
    Currently Being Moderated
    Thank you so much for your answer.

    I am aware of basic thread safety issues when it comes to member variables. I think my confusion was around my understanding of static nested classes. I was unsure whether or not a static nested class behaved the same as a regular top level class in regards to thread safety.

    However, in addition to your helpful answer I found the following information on Sun's site which gives a more thorough understanding: [http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html|http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html]

    Especially of interest:
    Note: A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience. 
  • 3. Re: Are static nested classes thread-safe?
    jwenting Journeyer
    Currently Being Moderated
    jduprez wrote:
    I'm not sure the notion that a variable is thread-safe means something. I would merely use "this usage of <variable> is thread-safe" or "all usages of ... are thread safe". Such a statement would have very little to do with how the variable is defined and much more with how the defining class enforces proper concurrent acces to the variable.
    Well, if you make a member static final it's pretty safe :)
  • 4. Re: Are static nested classes thread-safe?
    jduprez Pro
    Currently Being Moderated
    Joke-for-joke: a static final HashMap is anything but "thread-safe" - only the reference is immutable :o)
  • 5. Re: Are static nested classes thread-safe?
    843853 Newbie
    Currently Being Moderated
    I agree that thread-safe or not is for an operation, for a member, it has some sort of contextual confusion. For an operation or a member, if there's only one thread could access it atomically in one moment, we could call it thread-safe. Thus any synchronized method or immutable member (like primitive type) are thread-safe. Additionally for a member, if it's immutable, then it's thread-safe. However, I saw several people falls into a pit that immutable reference doesn't mean immutable instance. That is a static final HashMap still have thread-safe issue in practice because it's not a primitive. The put, get methods, which will be invoked probably, are not thread-safe although the reference to map is. So you need to be careful when you call methods of a static final object, they will not be thread-safe because you make the object immutable.
  • 6. Re: Are static nested classes thread-safe?
    jduprez Pro
    Currently Being Moderated
    Hello,

    I believe you understand what you're talking about, but you state it in a way that is very confusing for others.
    Let me correct this (essentially, incorrect uses of the terminology):
    I agree that thread-safe or not is for an operation, for a member, it has some sort of contextual confusion.
    Member has a much broader meaning in the [Java Language Specification|http://java.sun.com/docs/books/jls/third_edition/html/names.html#6.4] . Even "class member" applies to both an attribute, a method, or an inner class or interface.
    I think you mean "member variable" of a class (aka "attribute" or "field"). By the way, static or not is irrelevant to the rest of the discussion.
    For an operation or a member, if there's only one thread could access it atomically in one moment, we could call it thread-safe.
    Mmm. I was tempted to say yes (I'm reluctant to commit myself). With an emphasis on "_The encapsulating class_ makes this member's usage thread-safe".

    Still, just synchronizing each operation on a member is not enough to make all usages "thread-safe":
    Consider a java.util.Vector: each add/get is synchronized, so it is atomic, fine.
    However if one thread adds several values, let's say 3, one by one, to a vector that initially contains 0 values, and another thread reads the vector's size() (another properly synchronized method), the reader thread may witness a size anywhere among 0, 1, 2, 3, which, depending on the business logic, may be a severely inconsistent state.
    The client code would have to make extra work (e.g. synchronizing on the vector's reference before the 3 adds) to guarantee that the usage is thread-safe.
    Thus any synchronized method
    (With the limit stated above)
    or immutable member (like primitive type) are thread-safe.
    Additionally for a member, if it's immutable, then it's thread-safe.
    You mean, immutable primitive type, or immutable object. As stated previously, an immutable reference to a mutable object isn't thread-safe.
    a static final HashMap still have thread-safe issue in practice because it's not a primitive.
    The underlined part is incorrect. A primitive may have thread-safety issues (unless it's immutable), and an object may not have such issues, depending on a number of factors.
    The put, get methods, which will be invoked probably, are not thread-safe although the reference to map is.
    Yes. And even if the put/get methods were synchronized, the client code could see consistency issues in a concurrent scenario, as demonstrated above.

    Additional considerations:
    1) read/write of primitive types are not necessarily atomic: section [ §17.7 of the JLS|http://java.sun.com/docs/books/jls/third_edition/html/memory.html#17.7] explicitly states that writing a long or double value (2 32-bits words) may not be atomic, and may be subject to consistency issues in a concurrent scenario.
    2) The Java Memory Model explicitly allows non-synchronized operations on non-volatile fields to be implemented in a "thread-unsafe" way by the JVM. Leading way to a lot of unintuitive problems such as the "Double-Checked Locking idiom is broken". Don't make clever guess on code execution path unless you properly synchronize access to variables across threads.

    Edited by: jduprez on Mar 4, 2010 9:53 AM
  • 7. Re: Are static nested classes thread-safe?
    843853 Newbie
    Currently Being Moderated
    I agree with you and admit my usage of terminology is a little confusing probably because I'm not a native English speaker and I haven't read any language specification for a long time. Just want to add that sometimes thread-safe is not so vital. Like your example:

    Still, just synchronizing each operation on a member is not enough to make all usages "thread-safe":
    Consider a java.util.Vector: each add/get is synchronized, so it is atomic, fine.
    However if one thread adds several values, let's say 3, one by one, to a vector that initially contains 0 values, and another thread reads the vector's size() (another properly synchronized method), the reader thread may witness a size anywhere among 0, 1, 2, 3, which, depending on the business logic, may be a severely inconsistent state.
    (Sorry, don't know how to quote...)

    In business view, if the 3 add operations are in one transaction which should be view as an atomic operation, the write thread should do synchronization. Otherwise, there's no many reason to synchronize it, except concurrent modification problem. But this is out of this topic scope. So just ignore if I'm saying nonsense. :)
  • 8. Re: Are static nested classes thread-safe?
    jduprez Pro
    Currently Being Moderated
    I agree with you and admit my usage of terminology is a little confusing probably because I'm not a native English speaker
    No. And I'm not either.
    It's merely because "thread-safe" is not formally defined at the Java language level, and different people have a different understanding of what it means.
    and I haven't read any language specification for a long time.
    Sorry about flinging the JLS in the discussion, that might sound pedantic, but when we don't agree on terms in a discussion, we have to find a common ground for those term's definitions. And there isn't any universally accepted definition except what is by construction, the definitions from the language specification (granted, not my idea of a fun reading).
    Just want to add that sometimes thread-safe is not so vital. Like your example (...)
    So, you're not adding, merely repeating :o)
    (Sorry, don't know how to quote...)
    Using ">" chars, or using the " button (litterally: the button with a double-quote symbol).
    But this is out of this topic scope.
    Not so much. The OP's title asks whether nested classes, and the OP's text whether static inner classes' variables, are thread-safe. I reply that neither are more or less "thread-safe" than their top-level class counterparts, and I make a claim that both questions are ambiguous, since in my view "thread-safe" should not be applied to a class or a variable.
    So just ignore if I'm saying nonsense. :)
    Actively ignoring, then.
    No, I'm kidding :o)

    More seriously, I've googled for an authoritative source that would define "thread-safe", since most of the discussion is on a consensual meaning of this term, but haven't found it:
    - I'm sure I've seen standard JRE classes whose Javadoc claimed they were "thread-safe", which I thought was overstated (as only individual operations seemed to deserve this qualification). I've also seen warnings that a class or a whole framework (e.g. Swing) is +not+ thread-safe (which, although not clearly defined, is a correct warning that those should not be accessed by different threads).
    - I haven't found, and I think there isn't, a definition of "thread-safe" in the JLS.
    - the Wikitionary defines +thread-safe+ as +That can be safely accessed from multiple threads+. This entry also quotes the book "Java threads", by Scott Oaks & Henry Wong, stating: +"Only a few collection classes are threadsafe. As we'll see later, being threadsafe does not necessarily mean that you can safely use them in every multithreaded program"+. This provision is essentially what I've tried to defend in this topic. This book is a tutorial, but not a specification.
    - eventually, I found [this article|http://www.ibm.com/developerworks/java/library/j-jtp09263.html]. Not authoritative either, but I like his definitions. Brian Goetz identifies and names various levels of thread-related properties, namely +immutable+, +thread-safe+, +conditionally thread-safe+, +thread-compatible+, and... +thread-hostile+ :o) As per his terminology, and contrary to Oaks&Wong, the Vector class should be qualified of "conditionally thread-safe" (which is a weaker guarantee than "thread-safe").