executing block of code atomically

The answer depends on your definition of “atomic”

I know of three valid definitions for atomic:

  1. Atomic as in synchronized: only one thread can be executing the code at one time;
  2. Atomic as in ACID: all of the action/block happens, or none of it does;
  3. Atomic as in uninterruptible: once the block starts, it can’t be interrupted, even by task switching.

The first is probably what your professor meant, and it’s pretty easy to accomplish (see below).

The second (atomic as in ACID) can be approximated. See below.

The third simply cannot be guaranteed in Java – it doesn’t provide access to the “critical sections” primitives required for uninterruptibility. Fortunately, the need for this is pretty much restricted to operating systems and device drivers.

Atomic as in synchronized

This is relatively straightforward: simply enclose your block of code in a synchronized block. I’ve shown it as a discrete block below, but there are other options:

public void doSomethingQuasiAtomic() {
   synchronized (exampleLock) {
      // Your code block goes here. 
      // Only one thread will ever be in this block at a time.
      ...
   }
}

Atomic as in ACID

There’s no general-case solution for ACID atomicity, but it can be approximated, also using synchronized code. In order to do this, each of the parts of the action must be safely reversible.

This is how I’d approach it:

For the sake of argument, assume there’s a multipart action you need to do on an object we’ll call exampleObj, that you have three actions to be performed which can be safely reversed, and that all access to example is synchronized on exampleLock.


    synchronized(exampleLock) {
        boolean actionOneDone=false;
        boolean actionTwoDone=false;
        boolean actionThreeDone=false;
        try {
            actionOneDone=doActionOne(exampleObj);    // or perhaps exampleObj.doActionOne();
            if(actionOneDone) actionTwoDone=doActionTwo(exampleObj);
            if(actionTwoDone) actionThreeDone=doActionThree(exampleObj);
        } catch (Exception ex) {
            // Whatever seems appropriate here.
        } finally { 
            if (! (actionOneDone && actionTwoDone && actionThreeDone)) {
                /* At least one part failed.  Back out the completed actions in reverse order.  
                 * Note that we never need to reverse action three since if it completed, so did the others.
                 */
                if (actionTwoDone) {
                   reverseActionTwo(exampleObj);    // or perhaps exampleObj.reverseActionTwo();
                }
                if (actionOneDone) {
                   reverseActionOne(exampleObj);
                }
            }
        }
    }

Leave a Comment