Yesterday was day 1 of No Fluff Just Stuff in Boston. Here is a highlight of the sessions I attended.
David Geary presented an overview of JSF 2.0. The reference implementation is known as Project Mojarra which falls under the GlassFish family. The current reference implementation as well as the 2.0 RC can be downloaded from the project site.
Here are the highlights of what is new:
- Facelets (templated XHTML with an expression language) instead of JSP
- Annotations and convention instead of XML for configuration
- Bookmark friendly views
- Improved error messages
- Richer event model
- Ajax integration
I personally don’t do any web development, however I was interested in this topic as some of our Coherence*Web customers do use JSF.
The Java Memory Model
The first time I heard about the JMM was during my interview with Tangosol which incidentally occurred almost three years ago to the day. It isn’t often that you learn so much at a job interview. This was a clear indication that a job at Tangosol would result in me learning many new things from people much smarter than me. Consequently, many of the items covered during this talk I had at least passing familiarity with. However I was glad to see that Brian Goetz is as clear of a speaker as he is a writer – which is a real treat. The ability to transfer knowledge on complex topics not well understood by most people in the industry in such a straightforward manner is not something to be taken for granted.
I’ll try to provide a succinct 60 second overview of the JMM and why it matters if you’re a Java developer. It can be boiled down to a simple question:
If you assign a variable as such in thread A:
x = 5;
Under which circumstances will the following evaluate to true in thread B?
x == 5
If the write and read of variable x is done outside of a synchronization block or if x is not declared as volatile, then there is no guarantee that thread B will see the updated value. Straight from the slide deck:
- The memory effects of one thread may not be immediately visible to other threads
- Modern microprocessors exhibit a higher level of asynchronous and nondeterministic behavior than “when we were kids”
- Compilers may reorder instructions (if permitted by language semantics) to achieve higher performance
In a nutshell, modern multi processor and multi core machines perform aggressive caching to improve performance, at the cost of non deterministic behavior as described above. Therefore, any time variables are shared between threads, not only do you have to worry about ensuring that threads don’t step over each other (causing data corruption), but you also have to make sure that the updated value is visible to all threads.
Therefore the synchronized keyword actually performs double duty: it defines boundaries for critical sections, and it also ensures that variables written are immediately visible to all threads. The volatile keyword indicates that a variable should not be cached – its value will be immediately visible to all threads whenever it is updated.
Are All Web Applications Broken?
This talk builds upon the previous JMM talk and looks at a practical example of where this knowledge becomes important: web applications. Some web applications (i.e. servlets or web frameworks that run on servlets) are stateless, at least at the web tier. Many use the database for state, in which case the database is handling concurrency.
However, some web applications do track state internally, either as a member variable in the servlet (uncommon) or in the SessionContext (more common.) In this case it is definitely up to the developer to handle concurrency correctly, keeping in mind the lessons of the JMM.
The more subtle (and common) pitfall is in handling HttpSession objects. The common assumption is that access to a session object does not necessarily need to be thread safe since each session is scoped to a specific user who will presumably make one request at a time. However this assumption does not hold true in (at least) the following cases:
- Your app uses frames
- Your app uses Ajax
- Your app is a portlet
- Your user has an itchy trigger finger and likes to triple click on links
In these cases, you can easily have multiple threads accessing a session. Setting and getting attributes in a session is likely thread safe, but there’s no guarantee that the objects in the session themselves are thread safe. This is especially evident when distributing sessions, as this requires the container to serialize session attributes. Best practice for objects in a session are as follows:
- Use immutable variables (may have to combine with atomic operations via AtomicReference if there are check-then-act or read-modify-write actions.)
- Use thread safe objects (i.e. ConcurrentHashMap vs HashMap)
- Don’t put plain JavaBeans in a session!
For more, see the IBM developerWorks article.