How to use CompletableFuture without risking a StackOverflowError? - java

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);
}

Related

Avoid continuous "if (...)" checks while executing function

I have a function which looks like the following:
public Status execute() {
Status status = doSomething();
if (status != Status.ABORTED) {
status = doSomethingElse();
}
if (status != Status.ABORTED) {
status = doAgainSomethingElse(param1, param2);
}
if (status != Status.ABORTED) {
doSomethingWhichDoesntReturn(param3);
}
//etc.
return status;
}
So basically this function needs to return a Status. This is computed by a first function, and then recomputed by successive functions at the condition that, when those functions are executed, status != Status.ABORTED.
I would like to refactor this code but I don't have any valid idea in my mind.
If it was always status = someFunction(someParam), I would have used a list of Function<TypeInput, Status> and executed that list in loop:
List<Function<TypeInput, Status>> actions = List.of(function1, function2...);
for (Function<TypeInput, Status> f : actions) {
if (status != Status.ABORTED) {
status = f.apply(input);
}
}
The problem though is that each action may be different (sometimes it's a function which returns Status, sometimes there are parameters but not always the same size, sometimes it's just a void function etc.)
Does anyone have any idea?
Note: as soon as the status gets Status.ABORTED, I can return (I don't need to execute the rest of the function as anything is executed only if the status is not Status.ABORTED).
This looks like a good case for a try-catch approach. You could throw an exception in either of the methods e.g. StatusAbortedException and catch that to return the appropriate Status. It could look like this
try {
Status status = doSomethingElse();
status = doAgainSomethingElse(param1, param2);
status = doSomethingWhichDoesntReturn(param3); // this one probably does smth else
return status;
} catch (StatusAbortedException e){
// return Status.Aborted
}
Expanding on dave's idea (I was thinking along the same lines) you could provide a class that represents something like a conditional chain:
//individual "chain links", i.e. elements in the chain
interface ChainLink<V> {
V execute(V v) throws Exception;
}
class ConditionalChain<V> {
private final V initialValue;
private final Predicate<V> condition;
private final Collection<ChainLink<V>> links = new LinkedList<>();
//creates the chain with the initial condition value and the condition
public ConditionalChain(V initialValue, Predicate<V> condition) {
this.initialValue = initialValue;
this.condition = condition;
}
//execute the chain
public V execute() throws Exception {
V v = initialValue;
for( ChainLink<V> link : links ) {
//apply the condition first to test the initial value
if( !condition.test(v) ) {
break;
}
v = link.execute(v);
}
return v;
}
//chain a Callable that returns a new value
public ConditionalChain<V> chain(Callable<V> c) {
links .add(v -> c.call() );
return this;
}
//chain a Runnable that doesn't change the value
ConditionalChainer<V> chain(Runnable r) {
links .add(v -> { r.run(); return v; } );
return this;
}
//helper to get the chain started
public static <T> ConditionalChain<T> start(T initialValue, Predicate<T> condition) {
return new ConditionalChain<T>(initialValue, condition);
}
}
We're using out own (internal) functional interface to allow for returning the status even when using a runnable and to support exceptions being thrown.
This could also be expanded to allow for functions that take the current status as a parameter.
The chain itself could then look like this:
Status status = ConditionalChain.start(Status.RUNNING, s -> s != Status.ABORTED )
.chain(() -> doSomething())
.chain(() -> doSomethingElse())
.chain(() -> doSomethingWhichDoesntReturn(param3))
.chain(() -> doAgainSomethingElse("param1", "param2"))
.execute();
That way you'd be able to reuse the chain with different predicates. You could even return a "chain result" that contains the status as well as the index of the last element that has been executed, e.g. if you're interested that execution stopped after doSomethingElse().
There are several options you can go for. One option is a continuation passing style.
This doesn't look all that good in Java, but you can do something similar.
// This is pseudo code, intended to illustrate the concept.
cpsMethod(Arg... args, ClosureOverFunctionSoItIsNullary continuation) {
// do stuff
continuation.call();
}
So basically, the method gets what's supposed to happen next passed into it. There are some downsides to this approach in Java, namely that you don't have tail-call optimization, so you can get a stack overflow, and perhaps more importantly, it looks very different from normal Java.
// Illustrative pseudo code
return doSomething(() -> doSomethingElse(() -> doAgainSomethingElse(param1, param2, () -> doSomethingWhichDoesntReturn())));
This removes the ifs, or rather, put the test inside every method, which now has to decide if it's going to continue, or if it's going to just return Status.ABORTED.
You could of course make this thing prettier by putting the handling outside and just take the methods as producers, give in a Predicate/hardcode the test, and just offer varargs:
private continuationPasser(Supplier<Status> first, Supplier<Status>... rest) {
Objects.requireNonNull(first);
Status status = first.get();
for(Supplier<T> continuation : methods) {
status = continuation.get();
if(status == Status.ABORTED) {
return status;
}
}
}
Dirt simple code, does exactly what you'd expect, and now your call on top will go from:
public Status execute() {
Status status = doSomething();
if (status != Status.ABORTED) {
status = doSomethingElse();
}
if (status != Status.ABORTED) {
status = doAgainSomethingElse(param1, param2);
}
if (status != Status.ABORTED) {
doSomethingWhichDoesntReturn(param3);
}
//etc.
return status;
}
To something like:
public Status execute() {
return continuationPasser(
this::doSomething,
this::doSomethingElse,
() -> doAgainSomethingElse(arg1, arg2);
() -> doSomethingWhichDoesntReturn(arg3));
Except for, you know, the last one doesn't return anything.
If it's trivial to make it return something, then you could just do that. If that's not trivial, you can just change the type from a Supplier to a Function<Status, T>, and you can pass in the last status if you want.
But that's an option. Take a functional idea and make it work. This has the benefit of being very clear if you know what continuation passing is. You could generalize the idea to take in a predicate too, if you'd like. Another way to do this would be to change the continuationPasser a bit, to make it pass in the previous result, and let the methods themselves decide what they want to do.
Then continutationPasser can look like this:
continuationPasser(Function<Status, Status> first, Function<Status, Status>... rest) {
Objects.requireNonNull(first);
Status status = first.apply(Status.SOME_REASONABLE_VALUE_LIKE_NOT_STARTED);
// You could use some reduce function here if you want to.
// The choice of a loop here is just my personal preference.
for(Function<Status, Status> fun : rest) {
status = rest.apply(status);
}
return status;
}
This makes the continuation passer even simple.
You start off by applying the first function, to get a starting value. Then you just for-each over the rest of them. And they can just start with checking for the ABORTED status and exit early. You'll still have the ifs, but your main running code will look positively neat now.
You can always wrap your methods in something like:
Function<Status, Status> runIfNotAborted(Supplier<Status> supplier) {
return (Status s) -> s == ABORTED? ABORTED : supplier.get();
}
Function<Status, Status> returnPreviousStatus(Runnable code) {
return (s) -> {
code.run();
return s;
}
}
And now you don't even have to change your methods. (But if you were to do this style that might be a better option if it was available.)
public Status execute() {
return continuationPasser(
runIfNotAborted(this::doSomething),
runIfNotAborted(this::doSomethingElse),
runIfNotAborted(() -> doAgainSomethingElse(arg1, arg2)),
runIfNotAborted(returnPreviousStatus(() -> doSomethingWhichDoesntReturn(arg3)));
And now it's quite clear what's going on. We're building functions on top of functions, in what looks a bit like a functional decorator-pattern.
This is a very general idea, and you can do this more specialized or generalize it more if you want to. But be careful or you'll write a framework to not have to write an if/else. Jenkins uses this idea for its pipelines, but has a bit more stuff in it to pass along the environment as well for example.
You could have a closure over the different function signatures, so they all have the same signature, and then iterate over your list like you wanted until the status has changed. Something like this (but using a list, I was just a little lazy since this gets the point across):
https://onlinegdb.com/4JB1flbww
interface StatusInterface {
public String fixStatus();
}
public class Main
{
public static String A(boolean x) {
if (x) {
return "fixed";
}
return "broken";
}
public static String B(boolean x, boolean y) {
if (!x && y) {
return "fixed";
}
return "broken";
}
public static void main(String[] args) {
// Lambda Expression
boolean x = false;
boolean y = true;
StatusInterface AWrapped = () ->
{
return A(x);
};
StatusInterface BWrapped = () ->
{
return B(x, y);
};
// Calling the above interface
String status = "broken";
for (int i = 0; i < 2 && status.equals("broken"); i++) {
if (i == 0) status = AWrapped.fixStatus();
else status = BWrapped.fixStatus();
}
System.out.println(status);
}

Return datatype of original method

For example, I have a method which returns a boolean and I'm creating a new thread there, it's hard to return the boolean in the thread.
Let me show you what I mean with this example:
public boolean test() {
int a = 5;
int b = 3;
new Thread(() -> {
if (a > b) {
return true; //NOT POSSIBLE
} else {
return false;
}
}).start();
}
This is just an example. This would not work, I'd need to do something like this:
private boolean value;
public boolean test() {
int a = 5;
int b = 3;
new Thread(() -> {
if (a > b) {
value = true;
return;
} else {
value = false;
return;
}
}).start();
return value;
}
Now my questions, is there a way which is easier than thies? This could get messy if I have more methods like this in a class.
Regards
What you want is called futures, look at some examples
https://www.baeldung.com/java-future
Or for java 8 and later CompletableFuture https://www.baeldung.com/java-completablefuture , the guide also has an example how to wait for multiple values at once.
Basically you are giving out a promise of a value and the recipient can check whether the background thread has delivered the value already and/or wait until it is done.
Your example might look something like this:
public boolean test() throws Exception {
int a = 5;
int b = 3;
CompletableFuture<Boolean> future = CompletableFuture.supplyAsync(() -> {
if (a > b) {
return true;
} else {
return false;
}
});
return future.get();
}
When you start a new thread, the current method may complete (return value) before the new thread does.
One way to catch the result is to call, from your new thread, some method of a listener instance (typically the actionPerformed of an ActionListener) which you should pass as a parameter in calling your test()-method.
The basic idea of starting a new thread is to allow some time to pass in a lengthy method while your main program does more pressing things.

Check failure of putIfAbsent

Is this a valid code to write,if I wish to avoid unnecessary contains call?
I wish to avoid a contains call on every invocation,as this is highly time sensitive code.
cancelretryCountMap.putIfAbsent(tag,new AtomicInteger(0));
count = cancelretryCountMap.get(tag).incrementAndGet();
if(count > 10){
///abort after x retries
....
}
I am using JDK 7
Usually, you would use putIfAbsent like this:
final AtomicInteger present = map.get(tag);
int count;
if (present != null) {
count = present.incrementAndGet();
} else {
final AtomicInteger instance = new AtomicInteger(0);
final AtomicInteger marker = map.putIfAbsent(tag, instance);
if (marker == null) {
count = instance.incrementAndGet();
} else {
count = marker.incrementAndGet();
}
}
The reason for the explicit get being, that you want to avoid the allocation of the default value in the "happy" path (i.e., when there is already an entry with the given key).
If there is no matching entry, you have to use the return value of putIfAbsent in order to distinguish between
the entry was still missing (and the default value has been added due to the call), in which case the method returns null, and
some other thread has won the race and inserted the new entry after the call to get (in which case the method returns the current value associated with the given key)
You can abstract this sequence by introducing a helper method, e.g.,
interface Supplier<T> {
T get();
}
static <T> T computeIfAbsent(ConcurrentMap<K,T> map, T key, Supplier<? extends T> producer) {
final T present = map.get(key);
if (present != null) {
return present;
} else {
final T fallback = producer.get();
final T marker = map.putIfAbsent(key, fallback);
if (marker == null) {
return fallback;
} else {
return marker;
}
}
}
You could use this in your example:
static final Supplier<AtomicInteger> newAtomicInteger = new Supplier<AtomicInteger>() {
public AtomicInteger get() { return new AtomicInteger(0); }
};
void yourMethodWhatever(Object tag) {
final AtomicInteger counter = computeIfAbsent(cancelretryCountMap, tag, newAtomicInteger);
if (counter.incrementAndGet() > 10) {
... whatever ...
}
}
Note, that this is actually already provided in the JDK 8 as default method on Map, but since you are still on JDK 7, you have to roll your own, as is done here.

Deadlock in acquiring multiple locks

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.

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