Over a million developers have joined DZone.

Performance and Thread-Safe State Handling

DZone's Guide to

Performance and Thread-Safe State Handling

· Java Zone
Free Resource

Never build auth again! The Okta Developer Platform makes it simple to implement authentication, authorization, MFA and more in Java applications. Get started with the free API.

In my previous post I introduced using the state pattern and an AtomicReference to help maintain thread safety. My reason for starting to play with the pattern was really to make it easier to analyze the code and prove correctness, but obviously the question of performance inevitably comes up and it is interesting to know the trade-offs.

I set up a benchmark where ten threads would simultaneously try to execute the same code and each thread would just hammer away for an obscenely large number of times. First up for the test was the simple lamp:

public interface Lamp {
  boolean isOn();
  void setOn(boolean on);


The code to execute was:

              b = lamp.isOn();

I had an implementation with just a volatile field, an implementation with both methods synchronized, a hybrid implementation where the field was volatile and only the setter synchronized and an implementation using the state pattern. I also ran the bad non-thread-safe implementation. The results with the average time for one run through the code: volatile (669 ns), bad (697 ns), state (985 ns), hybrid (1570 ns), synchronized (2535 ns). Interestingly enough, the state pattern kicks butt. Actually the state pattern was even faster than volatile in the first tests I ran, but that is probably because I ran too few iterations to pay the full cost of garbage collection.

So how about a predicted worst case, the CoffeeMachine where the state changes on every method call?

public interface CoffeeMachine {
  void fillBeans(int beans);
  void fillWater(int water);
  Coffee makeCoffee(int water, int beans) throws OutOfWaterException, OutOfBeansException;

And the test code, same rules as above, ten threads whacking away:

          Random r = new Random();
              int w = r.nextInt(5);
              int b = r.nextInt(3);
              try {
              } catch (OutOfWaterException e) {
              } catch (OutOfBeansException e) {


This was a straight shoot-out between a synchronized implementation and a state pattern implementation. Result: synchronized (5021 ns), state (5333 ns). A slight victory for synchronization, yeah!

So how about adding some getters into the CoffeeMachine, how does that change things? The test code was changed to:

Random r = new Random(); 


int w = r.nextInt(5); 
if(cm.checkWater() < w*10)
int b = r.nextInt(3);
if (cm.checkBeans() < b*10)
catch (OutOfWaterException e)
catch (OutOfBeansException e)

With the getters present it makes sense to try a hybrid approach again. Result: state (2547 ns), hybrid (3675 ns), synchronized (4930 ns).

Conclusion: not only does the state pattern with an AtomicReference to an immutable internal state representation make it easier to manage code complexity, it is also beneficial from a performance point of view, being just slightly slower than synchronization in the worst case and twice as fast in normal cases.

Build and launch faster with Okta’s user management API. Register today for the free forever developer edition!


Opinions expressed by DZone contributors are their own.


Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.


{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}