Swap 2 values in 2 different AtomicReferences - java

I tried to implement a swap method for 2 AtomicReferences.
public void swap(AtomicReference<Object> a, AtomicReference<Object> b) {
while (true) {
Object value1 = a.get();
Object value2 = b.get();
if (a.compareAndSet(value1, value2) && b.compareAndSet(value2, value1)) return;
}
}
In my opinion, this solution is not correct. If multiple threads use this method at the same time, it could lead to the following scenario:
T1: ...get(); get(); compareAndSet() == true //-> BREAK (scheduler)
T2: ...get(); get(); compareAndSet() == true; compareAndSet() == true; return;
This would mean, T1 had set the value of a but will fail by setting the value of b. T1 would repeat the process EVEN if AtomicReference a has been set.
Does someone of you have a better idea, how to implement something like this? It would be easy, if you would just have one AtomicReference. Maybe it isn't possible using 2 AtomicReference's and I should consider using one AtomicReference that points to an Object[].
In Scala, this method is super easy to implement, since you have atomic blocks.
class Swappy[A](_a: A, _b: A) {
#volatile
var a = Ref(_a)
#volatile
var b = Ref(_b)
def swap(): Unit = {
atomic {
implicit tx =>
val tmp = a
a = b
b = tmp
}
}
def elems: (A, A) = (a.single(), b.single())
}

I created a solution with a different approach. This should be 100% thread safe. I switched to using just one AtomicReference. If anyone could find a better way, feel free to write an answer. :)
package test;
import java.util.concurrent.atomic.*;
public class ScalaSTMPendant {
AtomicReference<Object[]> a;
public ScalaSTMPendant(Object a, Object b) {
this.a = new AtomicReference<>(new Object[] {a,b});
}
public void swap() {
while (true) {
Object[] origin = a.get();
Object[] swapped = new Object[] {origin[1], origin[0]};
if (a.compareAndSet(origin, swapped)) return;
}
}
public Object[] elems() {
Object[] temp = a.get();
return new Object[] {temp[0], temp[1]};
}
}

Would an Exchanger help? I'm not sure who is swapping what, but an Exchanger would help you do a swap atomically.
Also, the scala sample above uses ScalaSTM. You could do the same in Java using another STM implementation (or even ScalaSTM). For example: Multiverse.

Related

what is proper java collection with unique element (like set) with get element feature

I Used Java HashSet for storing unique elements but now I want to retrieve element but HashSet does not has something like that, Here is what I want for my problem:
for my usecase LinkInfo hashCode() and equals() methods do not use LinkInfo.id field I want to get linkinfo instance from set and update all of its' fields except id field that should be from old instance
Set<LinkInfo> fooSet = new HashSet<>()
public void updateFoo(LinkInfo linkInfo) {
LinkInfo temp = fooSet.get(linkInfo);
linkInfo.setId(temp.getId());
// now update set
fooSet.remove(linkInfo)
fooSet.add(linkInfo)
}
Rather than
LinkInfo temp = fooSet.get(linkInfo);
the below logic is the same as what you seem to want
if (fooSet.contains(linkInfo)) {
temp = linkInfo;
}
I don't know why you're doing this, but to answer the question, yes you can do this, but you should use a map, like so:
import java.util.HashMap;
import java.util.Map;
public class Main {
static class Test {
public int a,b;
public Test(int a, int b) {
this.a = a;
this.b = b;
}
#Override
public boolean equals(Object obj) {
Test that = (Test)obj;
return this.a == that.a && this.b == that.b;
}
#Override
public int hashCode() {
return a ^ b;
}
}
public static void main(String[] args) {
Map<Test,Test> map = new HashMap<>();
Test t = new Test(1,2);
System.out.println(System.identityHashCode(t));
map.put(t, t);
Test t2 = new Test(1,2);
System.out.println(System.identityHashCode(t2));
System.out.println(System.identityHashCode(map.get(t2)));
}
}
Now you are able to retrieve the instance that you put into that map initially through an instance that is equal to it.
The program printed:
475266352
1355531311
475266352
on my computer. You can use a HashSet and iterate through it achieving the same result, but it won't be O(1).
You have a bit of a logical problem here. Why should an API that depends on equals() provide a method getElementEqualTo(e)? In order to use such a method, you need to present an object that, for the API's purposes, is equivalent to the desired result. What would be the point of that?
But that doesn't mean you're out of luck. I think you're saying that your LinkInfo class provides hashCode() and equals() methods suitable for identifying the object you want by means of a different object that you can obtain. In that case, it sounds like a HashMap could serve your purpose. Just map each key to itself.
HashMap<LinkInfo, LinkInfo> infos;
public void updateInfo(LinkInfo linkInfo) {
LinkInfo temp = infos.remove(linkInfo);
if (temp != null) {
linkInfo.setId(temp.getId());
}
infos.put(linkInfo, linkInfo);
}
I do agree with Scary answer above, but in case you want the exact reference that is stored in the Set instead of an similar equal object, you may use below code:
public void updateFoo(LinkInfo linkInfo) {
LinkInfo temp = null;
for(LinkInfo curLinkInfo:fooSet) if (curLinkInfo.equals(linkInfo))temp = curLinkInfo;
if(temp!=null)
linkInfo.setId(temp.getId());
// now update set
fooSet.remove(linkInfo)
fooSet.add(linkInfo)
}

Resolving multiple values returned from a query?

While this seems like a really simple problem, the only solution I've come up with is below, any suggestions for something less ugly with lower time complexity?
My application is in Java and is retrieving with a MS-sql DB using skife.jdbi.
Say I have a Tablewith columns A, B, and C where A and B form a primary key. And I want to retrieve C given a particularly A and B. This is easily accomplished. But what if I my throughput requirement is very high, so I want to make these Select statements in batches. I end up with something like the below:
Given a Set of Objects with values A and B, I iterate the List compiling all the values of A and B. I then run a query like SELECT A, B, C FROM tbl WHERE A IN :listOfAs AND B IN :listOfBs. I then iterate the results of the query, matching a result to the original object by comparing the A and B value. Which all sounds reasonable, but the code ends up looking like the below, which seems ugly and suboptimal?
class MyObject {
String A;
String B;
String C;
Object otherData;
#Override
public boolean equals(Object other) {
if (this == other) {
return true;
} else if (!(other instanceof MyObject)) {
return false;
} else {
return A.equals(other.A) && B.equals(other.B);
}
}
#Override
public int hashCode() {
return 31 * A.hashCode() + B.hashCode();
}
}
// populates the of objects with their proper C value
void retrieveC(Set<MyObject> input) {
Set<String> aValues = new HashSet<>();
Set<String> bValues = new HashSet<>();
for (MyObject object : input) {
aValues.add(object.A);
bValues.add(object.B);
}
// the dao executes the query mentioned above, and returns a Set of
// MyObject instances with members A, B, and C populated from the results.
// Any results that do not contain a value for A, B, and C (which
// shouldn't exit) are filtered out by the dao.
Set<MyObject> results = dao.selectC(aValues, bValues);
// ewww... O(n^2)
for (MyObject object : input) {
boolean resultFound = false;
for (MyObject result : results) {
if (object.equals(result)) {
object.C = result.C;
resultFound = true;
break;
}
}
if (!resultFound) {
// handle this case
}
}
}
I take it that ideal would be
SELECT A, B, C FROM tbl WHERE A+' '+B IN :listOfAandBs
That is not listOfAs x listOfBs (quadratic complexity) but listofAs . listOfBs (linear, in-product)
Instead of the DAO pattern you could turn to the fluent queries of JDBI.
This way you could switch batching to streaming. In the example given at the JDBI page you would exchange the StringBuilder() with something that allows you to stream your results to your receiver one by one as the database returns them.
If this is possible depends of course on your development environment.

Atomic compareAndSet but with callback?

I know that AtomicReference has compareAndSet, but I feel like what I want to do is this
private final AtomicReference<Boolean> initialized = new AtomicReference<>( false );
...
atomicRef.compareSetAndDo( false, true, () -> {
// stuff that only happens if false
});
this would probably work too, might be better.
atomicRef.compareAndSet( false, () -> {
// stuff that only happens if false
// if I die still false.
return true;
});
I've noticed there's some new functional constructs but I'm not sure if any of them are what I'm looking for.
Can any of the new constructs do this? if so please provide an example.
update
To attempt to simplify my problem, I'm trying to find a less error prone way to guard code in a "do once for object" or (really) lazy initializer fashion, and I know that some developers on my team find compareAndSet confusing.
guard code in a "do once for object"
how exactly to implement that depends on what you want other threads attempting to execute the same thing in the meantime. if you just let them run past the CAS they may observe things in an intermediate state while the one thread that succeeded does its action.
or (really) lazy initializer fashion
that construct is not thread-safe if you're using it for lazy initializers because the "is initialized" boolean may be set to true by one thread and then execute the block while another thread observes the true-state but reads an empty result.
You can use Atomicreference::updateAndGet if multiple concurrent/repeated initialization attempts are acceptable with one object winning in the end and the others being discarded by GC. The update method should be side-effect-free.
Otherwise you should just use the double checked locking pattern with a variable reference field.
Of course you can always package any of these into a higher order function that returns a Runnable or Supplier which you then assign to a final field.
// == FunctionalUtils.java
/** #param mayRunMultipleTimes must be side-effect-free */
public static <T> Supplier<T> instantiateOne(Supplier<T> mayRunMultipleTimes) {
AtomicReference<T> ref = new AtomicReference<>(null);
return () -> {
T val = ref.get(); // fast-path if already initialized
if(val != null)
return val;
return ref.updateAndGet(v -> v == null ? mayRunMultipleTimes.get() : v)
};
}
// == ClassWithLazyField.java
private final Supplier<Foo> lazyInstanceVal = FunctionalUtils.instantiateOne(() -> new Foo());
public Foo getFoo() {
lazyInstanceVal.get();
}
You can easily encapsulate various custom control-flow and locking patterns this way. Here are two of my own..
compareAndSet returns true if the update was done, and false if the actual value was not equal to the expected value.
So just use
if (ref.compareAndSet(expectedValue, newValue)) {
...
}
That said, I don't really understand your examples, since you're passing true and false to a method taking object references as argument. And your second example doesn't do the same thing as the first one. If the second is what you want, I think what you're after is
ref.getAndUpdate(value -> {
if (value.equals(expectedValue)) {
return someNewValue(value);
}
else {
return value;
}
});
You’re over-complicating things. Just because there are now lambda expression, you don’t need to solve everything with lambdas:
private volatile boolean initialized;
…
if(!initialized) synchronized(this) {
if(!initialized) {
// stuff to be done exactly once
initialized=true;
}
}
The double checked locking might not have a good reputation, but for non-static properties, there are little alternatives.
If you consider multiple threads accessing it concurrently in the uninitialized state and want a guaranty that the action runs only once, and that it has completed, before dependent code is executed, an Atomic… object won’t help you.
There’s only one thread that can successfully perform compareAndSet(false,true), but since failure implies that the flag already has the new value, i.e. is initialized, all other threads will proceed as if the “stuff to be done exactly once” has been done while it might still be running. The alternative would be reading the flag first and conditionally perform the stuff and compareAndSet afterwards, but that allows multiple concurrent executions of “stuff”. This is also what happens with updateAndGet or accumulateAndGet and it’s provided function.
To guaranty exactly one execution before proceeding, threads must get blocked, if the “stuff” is currently executed. The code above does this. Note that once the “stuff” has been done, there will be no locking anymore and the performance characteristics of the volatile read are the same as for the Atomic… read.
The only solution which is simpler in programming, is to use a ConcurrentMap:
private final ConcurrentHashMap<String,Boolean> initialized=new ConcurrentHashMap<>();
…
initialized.computeIfAbsent("dummy", ignore -> {
// stuff to do exactly once
return true;
});
It might look a bit oversized, but it provides exactly the required performance characteristics. It will guard the initial computation using synchronized (or well, an implementation dependent exclusion mechanism) but perform a single read with volatile semantics on subsequent queries.
If you want a more lightweight solution, you may stay with the double checked locking shown at the beginning of this answer…
I know this is old, but I've found there is no perfect way to achieve this, more specifically this:
trying to find a less error prone way to guard code in a "do (anything) once..."
I'll add to this "while respecting a happens before behavior." which is required for instantiating singletons in your case.
IMO The best way to achieve this is by means of a synchronized function:
public<T> T transaction(Function<NonSyncObject, T> transaction) {
synchronized (lock) {
return transaction.apply(nonSyncObject);
}
}
This allows to preform atomic "transactions" on the given object.
Other options are double-check spin-locks:
for (;;) {
T t = atomicT.get();
T newT = new T();
if (atomicT.compareAndSet(t, newT)) return;
}
On this one new T(); will get executed repeatedly until the value is set successfully, so it is not really a "do something once".
This would only work on copy on write transactions, and could help on "instantiating objects once" (which in reality is instantiating many but at the end is referencing the same) by tweaking the code.
The final option is a worst performant version of the first one, but this one is a true happens before AND ONCE (as opposed to the double-check spin-lock):
public void doSomething(Runnable r) {
while (!atomicBoolean.compareAndSet(false, true)) {}
// Do some heavy stuff ONCE
r.run();
atomicBoolean.set(false);
}
The reason why the first one is the better option is that it is doing what this one does, but in a more optimized way.
As a side note, in my projects I've actually used the code below (similar to #the8472's answer), that at the time I thought safe, and it may be:
public T get() {
T res = ref.get();
if (res == null) {
res = builder.get();
if (ref.compareAndSet(null, res))
return res;
else
return ref.get();
} else {
return res;
}
}
The thing about this code is that, as the copy on write loop, this one generates multiple instances, one for each contending thread, but only one is cached, the first one, all the other constructions eventually get GC'd.
Looking at the putIfAbsent method I see the benefit is the skipping of 17 lines of code and then a synchronized body:
/** Implementation for put and putIfAbsent */
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());
int binCount = 0;
for (Node<K,V>[] tab = table;;) {
Node<K,V> f; int n, i, fh;
if (tab == null || (n = tab.length) == 0)
tab = initTable();
else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
if (casTabAt(tab, i, null,
new Node<K,V>(hash, key, value, null)))
break; // no lock when adding to empty bin
}
else if ((fh = f.hash) == MOVED)
tab = helpTransfer(tab, f);
else {
V oldVal = null;
synchronized (f) {
if (tabAt(tab, i) == f) {
And then the synchronized body itself is another 34 lines:
synchronized (f) {
if (tabAt(tab, i) == f) {
if (fh >= 0) {
binCount = 1;
for (Node<K,V> e = f;; ++binCount) {
K ek;
if (e.hash == hash &&
((ek = e.key) == key ||
(ek != null && key.equals(ek)))) {
oldVal = e.val;
if (!onlyIfAbsent)
e.val = value;
break;
}
Node<K,V> pred = e;
if ((e = e.next) == null) {
pred.next = new Node<K,V>(hash, key,
value, null);
break;
}
}
}
else if (f instanceof TreeBin) {
Node<K,V> p;
binCount = 2;
if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
value)) != null) {
oldVal = p.val;
if (!onlyIfAbsent)
p.val = value;
}
}
}
}
The pro(s) of using a ConcurrentHashMap is that it will undoubtedly work.

Create and put a map value only if not already present, and get it: thread-safe implementation

What is the best way to make this snippet thread-safe?
private static final Map<A, B> MAP = new HashMap<A, B>();
public static B putIfNeededAndGet(A key) {
B value = MAP.get(key);
if (value == null) {
value = buildB(...);
MAP.put(key, value);
}
return value;
}
private static B buildB(...) {
// business, can be quite long
}
Here are the few solutions I could think about:
I could use a ConcurrentHashMap, but if I well understood, it just makes the atomic put and get operations thread-safe, i.e. it does not ensure the buildB() method to be called only once for a given value.
I could use Collections.synchronizedMap(new HashMap<A, B>()), but I would have the same issue as the first point.
I could set the whole putIfNeededAndGet() method synchronized, but I can have really many threads accessing this method together, so it could be quite expensive.
I could use the double-checked locking pattern, but there is still the related out-of-order writes issue.
What other solutions may I have?
I know this is a quite common topic on the Web, but I didn't find a clear, full and working example yet.
Use ConcurrentHashMap and the lazy init pattern which you used
public static B putIfNeededAndGet(A key) {
B value = map.get(key);
if (value == null) {
value = buildB(...);
B oldValue = map.putIfAbsent(key, value);
if (oldValue != null) {
value = oldValue;
}
}
return value;
}
This might not be the answer you're looking for, but use the Guava CacheBuilder, it already does all that and more:
private static final LoadingCache<A, B> CACHE = CacheBuilder.newBuilder()
.maximumSize(100) // if necessary
.build(
new CacheLoader<A, B>() {
public B load(A key) {
return buildB(key);
}
});
You can also easily add timed expiration and other features as well.
This cache will ensure that load() (or in your case buildB) will not be called concurrently with the same key. If one thread is already building a B, then any other caller will just wait for that thread.
In the above solution it is possible that many threads will class processB(...) simultaneously hence all will calculate. But in my case i am using Future and a single thread only get the old value as null hence it will only compute the processB rest will wait on f.get().
private static final ConcurrentMap<A, Future<B>> map = new ConcurrentHashMap<A, Future<B>>();
public static B putIfNeededAndGet(A key) {
while (true) {
Future<V> f = map.get(key);
if (f == null) {
Callable<B> eval = new Callable<V>() {
public B call() throws InterruptedException {
return buildB(...);
}
};
FutureTask<V> ft = new FutureTask<V>(eval);
f = map.putIfAbsent(arg, ft);
if (f == null) {
f = ft;
ft.run();
}
}
try {
return f.get();
} catch (CancellationException e) {
cache.remove(arg, f);
} catch (ExecutionException e) {
}
}
}
Thought maybe this will be useful for someone else as well, using java 8 lambdas I created this function which worked great for me:
private <T> T getOrCreate(Object key, Map<Object, T> map,
Function<Object, T> creationFunction) {
T value = map.get(key);
// if the doesn't exist yet - create and add it
if (value == null) {
value = creationFunction.apply(key);
map.put(label, metric);
}
return value;
}
then you can use it like this:
Object o = getOrCreate(key, map, s -> createSpecialObjectWithKey(key));
I created this for something specific but changed the context and code to a more general look, that is why my creationFunction has one parameter, it can also have no parameters...
also you can generify it more by changing Object to a generic type, if it's not clear let me know and I'll add another example.
UPDATE:
I just found out about Map.computeIfAbsent which basically does the same, gotta love java 8 :)

Is there any way I can return a value from a loop and continue from where I left off?

Is there any way I can return a value from a loop and continuing from where I left off ?
In the following snippet, I want to return the current value of currVm. But I am unable to do so.
In the innermost loop of the snippet :
while(c <= currVm) {
allocatedVm(currVm);
c++;
}
a function named allocatedVm is called. I want to return the value of currVm and start again from where I left off. Is there any way out ?
#Override
public int getNextAvailableVm() {
Set<String> dataCenters = confMap.keySet();
for (String dataCenter : dataCenters) {
LinkedList<DepConfAttr> list = confMap.get(dataCenter);
Collections.sort(list, new MemoryComparator());
int size = list.size() - 1;
int count = 0;
while(size >= 0) {
DepConfAttr dca = (DepConfAttr)list.get(count);
int currVm = dca.getVmCount();
int c = 0;
while(c <= currVm) {
allocatedVm(currVm); // RETURN currVm
c++;
}
count++;
size--;
}
}
}
The best approach would probably be to write a method returning an Iterable<Integer>. That's not as easy in Java as it is in languages which support generator functions (e.g. C# and Python) but it's still feasible. If the code is short, you can get away with a pair of (nested) anonymous inner classes:
public Iterable<Integer> foo() {
return new Iterable<Integer>() {
#Override public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
// Implement hasNext, next and remove here
};
}
};
}
In your case I'd be tempted to break it into a separate non-anonymous class though, just for simplicity.
Anyway, the point of using Iterable is that an Iterator naturally has state - that's its purpose, basically. So it's a good fit for your requirements.
Another rather simpler approach would be to return all of the elements in one go, and make the caller perform the allocation on demand. Obviously that doesn't work well if there could be a huge number of elements, but it would be easier to understand.
not sure i understand what you need, but:
if you wish to notify the caller of the method that you've got a value during the running of the method, but don't wish to exit the method just yet, you can use listeners.
just create an interface as a parameter to your function, and have a function inside that will have the object as a parameter.
example:
interface IGotValueListener
{
public void onGotValue(MyClass obj);
}
public int getNextAvailableVm(IGotValueListener listener)
{
...
if(listener!=null)
listener.onGotValue(...);
}
now , for calling the method, you do:
int finalResult=getNextAvailableVm(new IGotValueListener ()
{
... //implement onGotValue
};
You can return from anywhere in your method , by just putting the return keyword. If you want to put a functionality to resume ur method from different places then u need to factor ur method in that way. You can use labels and if statements, set some static variables to mark the last execution place. If your application is not multi-threaded then u need not to worry with the use of static variable synchronization. Also if your method is too big and becoming hard to follow/read, then think about breaking it into smaller ones.

Categories

Resources