Deadlock in acquiring multiple locks - java

I have a following code snippet (The code is in Java, but I have tried to reduce as much clutter as possible):
class State {
public synchronized read() {
}
public synchronized write(ResourceManager rm) {
rm.request();
}
public synchronized returnResource() {
}
}
State st1 = new State();
State st2 = new State();
State st3 = new State();
class ResourceManager {
public syncronized request() {
st2 = findIdleState();
return st2.returnResource();
}
}
ResourceManager globalRM = new ResourceManager();
Thread1()
{
st1.write(globalRM);
}
Thread2()
{
st2.write(globalRM);
}
Thread3()
{
st1.read();
}
This code snippet has the possibility of entering a deadlock with the following sequence of calls:
Thread1: st1.write()
Thread1: st1.write() invokes globalRM.request()
Thread2: st2.write()
Thread1: globalRM.request() tries to invoke st2.returnResource(), but gets blocked because Thread2 is holding a lock on st2.
Thread2: st2.write() tries to invoke globalRM.request(), but gets blocked because globalRM's lock is with Thread1
Thread3: st2.read(), gets blocked.
How do I solve such a deadlock? I thought about it for a while to see there is some sort of ordered locks approach I can use to acquire the locks, but I cannot think of such a solution. The problem is that, the resource manager is global, while states are specific to each job (each job has an ID which is sequential which can be used for ordering if there is some way to use order for lock acquisition).

There are some options to avoid this scenario, each has its advantages and drawbacks:
1.) Use a single lock object for all instances. This approach is simple to implement, but limits you to one thread to aquire the lock. This can be reasonable if the synchronized blocks are short and scalability is not a big issue (e.g. desktop application aka non-server). The main selling point of this is the simplicity in implementation.
2.) Use ordered locking - this means whenever you have to aquire two or more locks, ensure that the order in which they are aquired is the same. Thats much easier said then done and can require heavy changes to the code base.
3.) Get rid of the locks completely. With the java.util.concurrent(.atomic) classes you can implement multithreaded data structures without blocking (usually using compareAndSet-flavor methods). This certainly requires changes to the code base and requires some rethinking of the structures. Usually reqiures a rewrite of critical portions of the code base.
4.) Many problems just disappear when you consequently use immutable types and objects. Combines well with the atomic (3.) approach to implement mutable super-structures (often implemented as copy-on-change).
To give any recommendation one would need to know a lot more details about what is protected by your locks.
--- EDIT ---
I needed a lock-free Set implementation, this code sample illustrates it strengths and weaknesses. I did implement iterator() as a snapshot, implementing it to throw ConcurrentModificationException and support remove() would be a little more complicated and I had no need for it. Some of the referenced utility classes I did not post (I think its completely obvious what the missing referenced pieces do).
I hope its at least a little useful as a starting point how to work with AtomicReferences.
/**
* Helper class that implements a set-like data structure
* with atomic add/remove capability.
*
* Iteration occurs always on a current snapshot, thus
* the iterator will not support remove, but also never
* throw ConcurrentModificationException.
*
* Iteration and reading the set is cheap, altering the set
* is expensive.
*/
public final class AtomicArraySet<T> extends AbstractSet<T> {
protected final AtomicReference<Object[]> reference =
new AtomicReference<Object[]>(Primitives.EMPTY_OBJECT_ARRAY);
public AtomicArraySet() {
}
/**
* Checks if the set contains the element.
*/
#Override
public boolean contains(final Object object) {
final Object[] array = reference.get();
for (final Object element : array) {
if (element.equals(object))
return true;
}
return false;
}
/**
* Adds an element to the set. Returns true if the element was added.
*
* If element is NULL or already in the set, no change is made to the
* set and false is returned.
*/
#Override
public boolean add(final T element) {
if (element == null)
return false;
while (true) {
final Object[] expect = reference.get();
final int length = expect.length;
// determine if element is already in set
for (int i=length-1; i>=0; --i) {
if (expect[i].equals(element))
return false;
}
final Object[] update = new Object[length + 1];
System.arraycopy(expect, 0, update, 0, length);
update[length] = element;
if (reference.compareAndSet(expect, update))
return true;
}
}
/**
* Adds all the given elements to the set.
* Semantically this is the same a calling add() repeatedly,
* but the whole operation is made atomic.
*/
#Override
public boolean addAll(final Collection<? extends T> collection) {
if (collection == null || collection.isEmpty())
return false;
while (true) {
boolean modified = false;
final Object[] expect = reference.get();
int length = expect.length;
Object[] temp = new Object[collection.size() + length];
System.arraycopy(expect, 0, temp, 0, length);
ELoop: for (final Object element : collection) {
if (element == null)
continue;
for (int i=0; i<length; ++i) {
if (element.equals(temp[i])) {
modified |= temp[i] != element;
temp[i] = element;
continue ELoop;
}
}
temp[length++] = element;
modified = true;
}
// check if content did not change
if (!modified)
return false;
final Object[] update;
if (temp.length == length) {
update = temp;
} else {
update = new Object[length];
System.arraycopy(temp, 0, update, 0, length);
}
if (reference.compareAndSet(expect, update))
return true;
}
}
/**
* Removes an element from the set. Returns true if the element was removed.
*
* If element is NULL not in the set, no change is made to the set and
* false is returned.
*/
#Override
public boolean remove(final Object element) {
if (element == null)
return false;
while (true) {
final Object[] expect = reference.get();
final int length = expect.length;
int i = length;
while (--i >= 0) {
if (expect[i].equals(element))
break;
}
if (i < 0)
return false;
final Object[] update;
if (length == 1) {
update = Primitives.EMPTY_OBJECT_ARRAY;
} else {
update = new Object[length - 1];
System.arraycopy(expect, 0, update, 0, i);
System.arraycopy(expect, i+1, update, i, length - i - 1);
}
if (reference.compareAndSet(expect, update))
return true;
}
}
/**
* Removes all entries from the set.
*/
#Override
public void clear() {
reference.set(Primitives.EMPTY_OBJECT_ARRAY);
}
/**
* Gets an estimation how many elements are in the set.
* (its an estimation as it only returns the current size
* and that may change at any time).
*/
#Override
public int size() {
return reference.get().length;
}
#Override
public boolean isEmpty() {
return reference.get().length <= 0;
}
#SuppressWarnings("unchecked")
#Override
public Iterator<T> iterator() {
final Object[] array = reference.get();
return (Iterator<T>) ArrayIterator.get(array);
}
#Override
public Object[] toArray() {
final Object[] array = reference.get();
return Primitives.cloneArray(array);
}
#SuppressWarnings("unchecked")
#Override
public <U extends Object> U[] toArray(final U[] array) {
final Object[] content = reference.get();
final int length = content.length;
if (array.length < length) {
// Make a new array of a's runtime type, but my contents:
return (U[]) Arrays.copyOf(content, length, array.getClass());
}
System.arraycopy(content, 0, array, 0, length);
if (array.length > length)
array[length] = null;
return array;
}
}

The answer to any deadlock is to acquire the same locks in the same order. You'll just have to figure out a way to do that.

Related

How to use CompletableFuture without risking a StackOverflowError?

I want to walk the search space of an asynchronous function. I coded the logic as follows:
/**
* Assuming that a function maps a range of inputs to the same output value, minimizes the input value while
* maintaining the output value.
*
* #param previousInput the last input known to return {#code target}
* #param currentInput the new input value to evaluate
* #param function maps an input to an output value
* #param target the expected output value
* #return the minimum input value that results in the {#code target} output value
* <br>{#code #throws NullPointerException} if any argument is null
* <br>{#code #throws IllegalArgumentException} if {#code stepSize} is zero}
*/
private static CompletionStage<BigDecimal> optimizeInput(BigDecimal previousInput,
BigDecimal currentInput,
BigDecimal stepSize,
Function<BigDecimal, CompletionStage<BigDecimal>> function,
BigDecimal target)
{
return function.apply(currentInput).thenCompose(output ->
{
assertThat("stepSize", stepSize).isNotZero();
int outputMinusTarget = output.compareTo(target);
if (outputMinusTarget != 0)
return CompletableFuture.completedFuture(previousInput);
BigDecimal nextInput = currentInput.add(stepSize);
if (nextInput.compareTo(BigDecimal.ZERO) < 0)
return CompletableFuture.completedFuture(previousInput);
return optimizeInput(currentInput, nextInput, stepSize, function, target);
});
}
Unfortunately, if the function has a large search space this raises a StackoverflowError after some iterations. Is it possible to walk the search space iteratively, with a fixed-size stack?
you have the following recursion structure
CompletableFuture<T> compute(...) {
return asyncTask().thenCompose(t -> {
if (...)
return completedFuture(t);
} else {
return compute(...);
}
}
}
You can rewrite it avoiding completable future composition and its stack usage during completion.
CompletableFuture<T> compute(...) {
CompletableFuture<T> result = new CompletableFuture<>();
computeHelper(result, ...);
return result;
}
void computeHelper(CompletableFuture<T> result, ...) {
asyncTask().thenAccept(t -> {
if (...) {
result.complete(t);
} else {
computeHelper(result, ...);
}
});
}
if asyncTask() is not really asynchronous and just use the current thread, you must replace thenAccept with one of its asynchronous versions to use the executor task queue instead of the thread stack.
dfogni's answer should work fine -- but for completeness, it is possible to avoid doing the executor handoffs in the case where the method is synchronous using a trampolining type technique.
To make it easier, I've introduced a class that capture the state that is changing between iterations and introducing methods that implement your completion checks and generate the next state. I believe this is the same as your original logic, but you can triple check.
private static CompletionStage<BigDecimal> optimizeInput(BigDecimal previousInput,
BigDecimal currentInput,
BigDecimal stepSize,
Function<BigDecimal, CompletionStage<BigDecimal>> function,
BigDecimal target) {
class State {
BigDecimal prev;
BigDecimal curr;
BigDecimal output;
State(BigDecimal prev, BigDecimal curr, BigDecimal output) {
this.prev = prev;
this.curr = curr;
this.output = output;
}
boolean shouldContinue() {
return output.compareTo(target) == 0 && curr.add(stepSize).compareTo(BigDecimal.ZERO) >= 0;
}
CompletionStage<State> next() {
BigDecimal nextInput = curr.add(stepSize);
return function.apply(nextInput).thenApply(nextOutput -> new State(curr, nextInput, nextOutput));
}
}
/* Now it gets complicated... we have to check if we're running on the same thread we were called on. If we
* were, instead of recursively calling `next()`, we'll use PassBack to pass our new state back
* to the stack that called us.
*/
class Passback {
State state = null;
boolean isRunning = true;
State poll() {
final State c = this.state;
this.state = null;
return c;
}
}
class InputOptimizer extends CompletableFuture<BigDecimal> {
void optimize(State state, final Thread previousThread, final Passback previousPassback) {
final Thread currentThread = Thread.currentThread();
if (currentThread.equals(previousThread) && previousPassback.isRunning) {
// this is a recursive call, our caller will run it
previousPassback.state = state;
} else {
Passback passback = new Passback();
State curr = state;
do {
if (curr.shouldContinue()) {
curr.next().thenAccept(next -> optimize(next, currentThread, passback));
} else {
complete(curr.prev);
return;
}
// loop as long as we're making synchronous recursive calls
} while ((curr = passback.poll()) != null);
passback.isRunning = false;
}
}
}
InputOptimizer ret = new InputOptimizer();
function.apply(currentInput)
.thenAccept(output -> ret.optimize(
new State(previousInput, currentInput, output),
null, null));
return ret;
}
Ok, so it's pretty complicated. Also, note that this requires your function will never throw an exception or complete exceptionally which could be problematic. You can generify this so you only have to write it once though (with correct exception handling), which can be found in the asyncutil library (Disclaimer: I am a co-author of this library). There might be other libraries with similar functionality, most likely a mature reactive library like Rx. Using asyncutil,
private static CompletionStage<BigDecimal> optimizeInput(BigDecimal previousInput,
BigDecimal currentInput,
BigDecimal stepSize,
Function<BigDecimal, CompletionStage<BigDecimal>> function,
BigDecimal target) {
// ... State class from before
return function
.apply(currentInput)
.thenCompose(output -> AsyncTrampoline.asyncWhile(
State::shouldContinue,
State::next,
new State(previousInput, currentInput, output)))
.thenApply(state -> state.prev);
}

Using a class to find errors in data structures

I need to use the class ReturnObjectImpl to basically find errors when I add an element to the ArrayList data structure class (this is a university assignment).
I am not sure how I get my functions in the ArrayList class to return ReturnObject. I need some way of passing everything through to ReturnObject, checking if there is an error (which I am not sure how to do either) and then providing either an error message or the object.
public interface ReturnObject {
/**
* Returns whether there has been an error
* #return whether there has been an error
*/
public boolean hasError();
/**
* Returns the error message.
*
* This method must return NO_ERROR if and only if
* {#hasError} returns false.
*
* #return the error message
*/
public ErrorMessage getError(); //Changes the return to a String has in the interface ErrorMessage is throwing an error - if marks are deducted, please discuss with me
/**
* Returns the object wrapped in this ReturnObject, i.e. the
* result of the operation if it was successful, or null if
* there has been an error.
*
* Note that the output of this method must be null if {#see
* hasError} returns true, but the opposite is not true: if
* {#see hasError} returns false, this method may or may not
* return null.
*
* #return the return value from the method or null if there has been an error
*/
public Object getReturnValue();
}
And then there is the class itself (which in currently incomplete):
public class ReturnObjectImpl implements ReturnObject {
// Constructor for successful operation
ReturnObjectImpl (Object c){
if (!hasError()){
getReturnValue(c);
}
}
// Constructor for error
ReturnObjectImpl (){
if (hasError()){
// getError();
}
}
public boolean hasError() {
//returns true or false depending on if there is an error
return null;
}
public ErrorMessage getError() { //Changes the return to a String has in the interface ErrorMessage is throwing an error - if marks are deducted, please discuss with me
//returns the error message is hasError == true or NO_ERROR if hasError() returns false
return ErrorMessage;
}
public Object getReturnValue() {
// TODO Auto-generated method stub
return null;
}
}
And finally the ArrayList class
public class ArrayList implements List{
public static final int CAPACITY=16;
private int size = 0;
private Object[] data;
//constructors
public ArrayList() {
data = new Object[CAPACITY];
} //Constructs arraylist with default capacity
public ArrayList(int capacity) { // Constructs arraylist with given capacity
data = new Object[capacity];
System.out.println("Created an ArrayList of capacity " + capacity);
}
public boolean isEmpty(){
return (size == 0);
}
public int size(){
System.out.println("The ArrayList is not full, but currently has " + size + " indexs");
return size;
}
public ReturnObject get(int index){
return null; //INCOMPLETE
}
public ReturnObject remove(int index){
return null;
}
public ReturnObject add(int index, Object item){
if(index <= size && index < data.length){
for (int x = size-1; x >= index; x--){
data[x+1] = data[x];
size++;
}
data[index] = item;
System.out.println("Added to array at " + index);
}
return null;
}
public ReturnObject add(Object item){
if (data[0] == null){
data[0] = item;
}
//int adding = size + 1;
data[size] = item;
System.out.println("Added item to index " + size);
size++;
return null;
}
//added - but DELETE BEFORE SUBMITTING
public void printAll(){
for(int x = 0; x < data.length; x++){
System.out.println(data[x]);
}
}
}
In short, I have two issues:
1. What the functions for error checking should look like in returnObjectImpl
2. More significantly, how I supposed to send the results of, say, public ReturnObject add(Object item) from ArrayList class to ReturnObjectImpl.
If List is the java.util.List interface, you have some serious mistakes here:
List is a generic interface, but your ArrayList is not generic. (If you were coding this for Java 1.4.x, that would be OK. But Java 1.4.x was retired > 10 years ago!)
Your ArrayList methods are incompatible with the java.util.List API. For example, add should return a boolean, get should return the element type (or Object if you are ignoring generics) not some other type.
If not ... then calling the interface List is a bad idea. Ditto for ArrayList. You shouldn't "borrow" the names of standard classes and interfaces like this. It will get you into trouble.
To answer your questions:
1) What the functions for error checking should look like in returnObjectImpl.
There is no returnObjectImpl method. And the error checking does not belong in the ReturnObjectImpl class. That class (per its name and API design) is simply a "holder" that represents either a value or an error condition. The actual error checking code belongs in your array list class; e.g. some thing like this.
if (/* some error */) {
return new ReturnObjectImpl(/* some error message */);
}
2) More significantly, how I supposed to send the results of, say, public ReturnObject add(Object item) from ArrayList class to ReturnObjectImpl.
if (/* not an error */) {
return new ReturnObjectImpl(/* the value */);
}
Obviously you are going to have to redesign the ReturnObjectImpl constructors to make that work.
Opinion: I think someone may have gotten into the "don't use exceptions" mindset that afflicts1 some people who have learned to program in (say) C or C++. Without getting into the debate over whether exceptions are "good" or "bad", the fact remains that they are an integral part of the Java language, and they are used consistently throughout the the Java language and class libraries. You cannot avoid them, and you will hurt yourself if you try.
If this was your design, and you really want to avoid exceptions this much ... you should be using a different programming language2.
1 - That isn't intended to be perjorative, but I'm afraid that "avoid exceptions" thinking rarely (if ever) gives a good outcome in terms of Java productivity or maintainability.
2 - I'm reminded of the line "Real programmers can write FORTRAN in any language".

Hash Set add method is not working fine

I wrote a dummy program , that adds object in Hash Set. I created a class Car that has capacity of 5 people.
Now issue is i got different out put from different Main programs .
Kindly find the 2-Main programs below.
First Main Program is
public class Main_1 {
static int counter = 0;
public static void main(String args[]) {
Car car = new Car();
for (int i = 0; i < 20; i++) {
car.add(new Person());
}
car.done();
}
}
The out put of Main_1 is : Exception in thread "main" java.lang.IllegalStateException: I'm full
at Car.add(Car.java:10)
at Main_1.main(Main_1.java:8)
Second Main program is
public class Main_2 {
static int counter = 0;
static Car car = new Car();
public static void main(String args[]) {
car.add(new RecursivePerson());
car.done();
}
static class RecursivePerson extends Person {
public int hashCode() {
if (++counter < 20) {
car.add(new RecursivePerson());
}
return super.hashCode();
}
}
}
The out put of Main_2 is I'm a car with 20 people!
Below is the business logic of my program.
import java.util.HashSet;
import java.util.Set;
public class Car {
private static final int CAPACITY = 5;
private Set<Person> people = new HashSet<Person>();
public synchronized void add(Person p) {
if (people.size() >= CAPACITY) {
throw new IllegalStateException("I'm full");
} else {
people.add(p);
}
}
public synchronized void done() {
if (people.size() == 20) {
// The goal is to reach this line
System.out.println("I'm a car with 20 people!");
}
}
}
class Person {
}
Can some one tell my why java is behaving like this.
The difference is because of the way that a HashSet works: if you add an new element to it, it first checks if the object is already in the set, and if it isn't, it adds this to the set. In order to check if the object is in the set, it call hashCode() on the object.
Your second program is specifically designed to bypass the capacity check of the car. You override hashCode() in the objects you add to the hashset. This method is called by the HashSet.add method, but before the object was actually added to the set. In the overridden hashCode() method you add the additional elements to the set. That is, if Car.add() is called, the size of the hash set is always 0, and the capacity check will always pass.
HashSets are implemented using a HashMap. Let us have a look at the source HashSet's source for add, according to GrepCode:
public boolean add(E e)
{
return map.put(e, PRESENT)==null;
}
Let us follow this to the put implementation in HashMap, according to GrepCode:
public V More ...put(K key, V value)
{
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next)
{
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
{
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
}
Your object is added in the last line with the use of addEntry. However, hashCode is called in the 3rd line before the entry is added; in the end, this cause put to be called again. Because your hashCode method adds until you have 20 element the size of the set is 20 in the end.
It is because in Main_2 you are calling add recursively. The initial call to .add() method will not return to actually increment the size of people list. So, people.size() so it will always return 0, altough you added a lot of elements there.
if you do a little debugging, you will see the callstack after a couple of iterations in Main_2 looks like this:

LinkedList.contains execution speed

Why Methode LinkedList.contains() runs quickly than such implementation:
for (String s : list)
if (s.equals(element))
return true;
return false;
I don't see great difference between this to implementations(i consider that search objects aren't nulls), same iterator and equals operation
Let's have a look at the source code (OpenJDK version) of java.util.LinkedList
public boolean contains(Object o) {
return indexOf(o) != -1;
}
public int indexOf(Object o) {
int index = 0;
if (o==null) {
/* snipped */
} else {
for (Entry e = header.next; e != header; e = e.next) {
if (o.equals(e.element))
return index;
index++;
}
}
return -1;
}
As you can see, this is a linear search, just like the for-each solution, so it's NOT asymptotically faster. It'd be interesting to see how your numbers grow with longer lists, but it's likely to be a constant factor slower.
The reason for that would be that this indexOf works on the internal structure, using direct field access to iterate, as opposed to the for-each which uses an Iterator<E>, whose methods must also additionally check for things like ConcurrentModificationException etc.
Going back to the source, you will find that the E next() method returned by the Iterator<E> of a LinkedList is the following:
private class ListItr implements ListIterator<E> {
//...
public E next() {
checkForComodification();
if (nextIndex == size)
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.element;
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
This is considerably "busier" than the e = e.next; in LinkedList.contains! The iterator() of a LinkedList is actually a ListIterator, which has richer features. They aren't needed in your for-each loop, but unfortunately you have to pay for them anyway. Not to mention all those defensive checks for ConcurrentModificationException must be performed, even if there isn't going to be any modification to the list while you're iterating it.
Conclusion
So yes, iterating a LinkedList as a client using a for-each (or more straightforwardly, using its iterator()/listIterator()) is more expensive than what the LinkedList itself can do internally. This is to be expected, which is why contains is provided in the first place.
Working internally gives LinkedList tremendous advantage because:
It can cut corners in defensive checks since it knows that it's not violating any invariants
It can take shortcuts and work with its internal representations
So what can you learn from this? Familiarize yourself with the API! See what functionalities are already provided; they're likely to be faster than if you've had to duplicate them as a client.
I decided to test this and came out with some interesting result
import java.util.LinkedList;
public class Contains {
private LinkedList<String> items = new LinkedList<String>();
public Contains(){
this.addToList();
}
private void addToList(){
for(int i=0; i<2000; i++){
this.items.add("ItemNumber" + i);
}
}
public boolean forEachLoop(String searchFor){
for(String item : items){
if(item.equals(searchFor))
return true;
}
return false;
}
public boolean containsMethod(String searchFor){
if(items.contains(searchFor))
return true;
return false;
}
}
and a JUnit testcase:
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class ContainsTest {
#Test
public void testForEachLoop(){
Contains c = new Contains();
boolean result = c.forEachLoop("ItemNumber1758");
assertEquals("Bug!!", true, result);
}
#Test
public void testContainsMethod(){
Contains c = new Contains();
boolean result = c.containsMethod("ItemNumber1758");
assertEquals("Bug!!", true, result);
}
}
This funny thing is when I run the JUnit test the results are :
- testForEachLoop() - 0.014s
- testContainsMethod() - 0.025s
Is this true or I am doing something wrong ?

Does AtomicBoolean not have a negate() method?

Does java.util.concurrent.atomic.AtomicBoolean not have a method that can atomically negate/invert the value? Can I do it another way? Am I missing something?
Little old... but didn't really feel the answers were great.
Would have to totally disagree that this is not common or only useful in hardware. You may want a number of threads to toggle on a single variable with equal likelihood... I used the AtomicLong to make a fake boolean. This was adopted from a JMS MessageListener that I needed to respond a particular message half the time and another type the other half.
public class Mock {
private static AtomicLong count = new AtomicLong(0);
public boolean respond() {
long currentCount = count.getAndIncrement();
if (currentCount % 2 == 0) {
return true;
} else {
return false;
}
}
}
My naive implementation would be this:
boolean v;
do {
v=atomicBoolean.get();
} while(!atomicBoolean.compareAndSet(v, !v));
You can emulate AtomicBoolean.negate() by using AtomicInteger.getAndIncrement() and considering even numbers as true and odd numbers as false.
The actual value of the number should be ignored so you don't care about integer overflows.
The solution suggested in the book The CERT Oracle Secure Coding Standard for Java is the following:
import java.util.concurrent.atomic.AtomicBoolean;
final class Flag {
private AtomicBoolean flag = new AtomicBoolean(true);
public void toggle() {
boolean temp;
do {
temp = flag.get();
} while(!flag.compareAndSet(temp, !temp));
}
}
Using the AtomicBoolean#compareAndSet() method and a while loop you can implement a method to toggle the value of an AtomicBoolean in a thread-safe manner like this:
public static boolean negate(AtomicBoolean ab) {
// get the oposite value
boolean newVal = !ab.get();
// try to set the new value if the current value is the oposite of the new value
while (!ab.compareAndSet(!newVal, newVal)) {
// if the value we try to set was already set in the mean-time
// then toggle the new value and try again
newVal = !newVal;
}
// return the value we finally could set
return newVal;
}
If you are dealing with java 9 or later I suggest:
/**
* Flip the AtomicBoolean.
* Sets the boolean value to false if it is true, and to true if it is false
* with memory effects as specified by {#link java.lang.invoke.VarHandle#setVolatile}.
*
* #param atomicBoolean atomicBoolean
* #return new boolean value of AtomicBoolean
* #see AtomicInteger#accumulateAndGet(int x, IntBinaryOperator accumulatorFunction)
* #since 9
*/
public static final boolean flip(AtomicBoolean atomicBoolean) {
boolean prev = atomicBoolean.get(), next = false;
for (boolean haveNext = false; ; ) {
if (!haveNext) {
next = !prev;
}
if (atomicBoolean.weakCompareAndSetVolatile(prev, next)) {
return next;
}
haveNext = (prev == (prev = atomicBoolean.get()));
}
}
Or if you want get it directly...
https://github.com/XenoAmess/commonx/blob/master/src/main/java/com/xenoamess/commonx/java/util/concurrent/atomic/AtomicBooleanUtilsx.java

Categories