Java – executes code blocks atomically
How would you answer the following questions?
Will I achieve this through the production method?
public final AtomicInteger x = new AtomicInteger(0);
Then make sure to return the get statement:
x.get()
If I wanted to increase the value of X, would I do that?
x.getAndIncrement();
Solution
The answer depends on your definition of "atom"
I know three valid atomic definitions:
>Atoms in synchronization: only one thread can execute code at a time; > Atoms in acid: all actions / blocks will occur or will not occur; > Uninterrupted atom: once the block is started, it will not be interrupted even through task switching
The first may be what your professor means and is easy to implement (see below)
The second (atom in acid) can be approximated See below
The third is simply not guaranteed in Java - it does not provide access to the "critical parts" primitives required for uninterrupted Fortunately, the need for this is almost limited to operating systems and device drivers
Atoms in synchronization
This is relatively simple: just include the code block in the synchronization block I have shown it as the following discrete block, 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. ... } }
Atoms in acid
There is no general solution for acid atomicity, but it can also be approximated by synchronous code To do this, each part of the action must be safe and reversible
This is how I approach it:
For the sake of argument, suppose you need to perform multipart operations on the object we call exampleobj. You can perform three operations that can be safely undone, and you can synchronize all access to the example on examplelock
synchronized(exampleLock) { boolean actionOneDone=false; boolean actionTwoDone=false; boolean actionThreeDone=false; try { actionOneDone=doActionOne(exampleObj); // or perhaps exampleObj.doActionOne(); actionTwoDone=doActionTwo(exampleObj); 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); } } } }