Monday, March 31, 2008

Java Thread-safe State Design Pattern

Thread-safe State


Apart from the things mentioned here, this pattern also conveys the intent and benefits of the GoF State pattern, being an extension thereof. The term "behaviour" is interpreted more strictly so that an object is always considered to change its behaviour when its state changes.

Intent


Make sure that an object is observable only in a valid consistent state and that transitions between valid consistent states are atomic and side-effects occur if and only if the associated transition occurs validly.

Motivation


Consider a class where behaviour depends on more than one field and/or side-effects occur as a result of certain state-changes. Such behaviour can be very difficult to analyze for thread-safety and the safe classic approach is to synchronize all methods. Such behaviour can also be difficult to analyze for logical correctness, bringing the motivation for the state pattern into play.

The key idea is to leverage the state pattern and store the current state in an AtomicReference. Current state should be represented by an immutable object. State transitions are performed by a compareAndSet (CAS) operation and a retry on failure. For transitions with side-effects, the CAS is performed to a boilerplate blocking state, the side effects performed, the resultant state set and the blocking state released, whereby each thread released from the blocking state retries the attempted operation on the resulting state. The CAS always compares with the "this" reference of the state instance being transitioned from and can only succeed for one thread, all other threads attempting a simultaneous transition have to retry on the new state.

Applicability


Any object that has a method that has a more complex interaction with the object state than one of either a simple get or a simple set (in which case just marking the field volatile is simpler and more performant).

Structure (given as implementation examples)


Delegate all calls to an immutable state instance:

class Implementation implements Interface {
private final AtomicReference state;

public ... doSomething(...) {
return state.get().doSomething(...);
}

private class StateA implements Interface {
private final ... valueX;
private final ... valueY;

public ... doSomething(...) {
.... valueX ... valueY ...
}
}
}

Simple state changes performed by CAS or retry:

class Implementation implements Interface {
private final AtomicReference state;

public void setX(y) {
state.get().setX(y);
}

private class StateA implements Interface {
private final ... x;

public void setX(y) {
if (!state.compareAndSet(this, new StateA(y))) {
state.get().setX(y);
}
}
}
}

State changes with side-effects CAS to a blocking state first:

class Implementation implements Interface {
private final AtomicReference state;

public void printAndSetX(y) {
state.get().printAndSetX(y);
}

private class StateA implements Interface {
private final ... x;

public void printAndSetX(y) {
BlockingState guard = new BlockingState();
if (state.compareAndSet(this, guard)) {
try {
print(x);
state.set(new StateA(y));
} finally {
guard.release();
}
}
}
}

private class BlockingState implements Interface {
private final CountDownLatch latch = new CountDownLatch(1);

public void printAndSetX(y) {
try {
latch.await();
} catch (InterruptedException e) {
// Don't care.
}
state.get().printAndSetX(y);
}

private void release() {
latch.countDown();
}
}
}

Participants



  • Interface - defines the public interface.

  • Implementation - maintains an AtomicReference to current StateImplementation, implements the public interface.

  • StateImplementation - the implementation of the public interface for a particular state.

  • BlockingState - specialized boilerplate StateImplementation that blocks all calls until released and then delegates to the current state.


Collaborations



  • Implementation delegates relevant (usually all) calls to the current StateImplementation.

  • StateImplementation performs state transitions by a state.compareAndSet(this, nextState) or retry the transition on the current state (which is different from "this" since CAS failed) so that each state object can only be transitioned from once.

  • BlockingState blocks all calls until released, thereupon retries on new current StateImplementation.


Consequences



  1. Interactions with the object always occur with a consistent state of the object, the immutability of the state delegate guaranteeing a consistent result of the interaction and each separate interaction is therefore in effect atomic.

  2. State transitions are explicit and atomic.

  3. Performance seems to be as good as or better than a straightforward non-thread-safe implementatin with mutable fields. Performance is better than that of synchronization (compare "optimistic locking" versus "read/write locking") for applicable objects if some interactions do not entail state changes, especially when the object is reachable from more than one thread (even if access is never contended).

18 comments:

marry said...

Blogs are so informative where we get lots of information on any topic. Nice job keep it up!!
_____________________________

Dissertation Editing

Dissertation Help said...

Wonderful post, thanks for putting this together! "This is obviously one great post. Thanks for the valuable information and insights you have so provided here. Keep it up!"
---------------------------------------------
Dissertation Writing | Dissertation Advice

dissertation said...

it's good to see this information in your post, i was looking the same but there was not any proper resource, thanx now i have the link which i was looking for my research.

UK Dissertations Help

preety said...
This comment has been removed by the author.
Aria Kerry said...
This comment has been removed by the author.
Dissertation Writing service said...

This post includes all information that I have always required. Although on internet we find a lot of information but the practical information is limited which you have originated in this post.

Dissertation writing services

Dissertation Writing Help said...

well i like your post . .the information in your post is quite good;) . .nice work .. Thanks a lot keep sharing:)

Dissertation Writing Services

Dissertation Writing Help said...

Your blog is really helps for my search and i really like it.. Thanks a lot..:)

Dissertation Editing Services

Ak Sağlık said...

This is a really stupid question but what language does the script need to be in?
Saç Ekimi

free google sms said...

Give The world full of loves! The Great Loves will be giving back to Human!
Nursing assistant classes

Magento said...

Thanks for the coding guidelines.Java some times became very critical.Its very informative and easy coding.
Bahrain website design company

Osse said...

i really like your post .. i would like to bookmark your site for my future needs :)
dissertations

Melany Flemmings said...

Valuable info. A very nice informational blog. Blessings.

HOTEL SUITES IN WASHINGTON DC

Unknown said...

It’s good stuff here and I have been looking for such information for many days. Thanks for sharing this information.
dissertation writing assistance

kathleenswatts12 said...

Wonderful article, thanks for putting this together! "This is obviously one great post. Thanks for the valuable information and insights you have so provided here. Keep it up!"
masters thesis paper

Jacob Hubbard said...

I want to say one thing that you have good command on the topic. Your website in very informative. I will keep on coming here to read new articles. Thanks.
dissertation service writing

ambercummings78 said...

I want to say that you have good writing skills. You have explained it well. I admire your work. Thanks for sharing.
essay title

DEWHURST TOULSON said...

the implementation of the public interface for a particular state.
dissertation-topics-examples.info