Skip to content

Instantly share code, notes, and snippets.

@atnak
Created September 7, 2016 02:39
Show Gist options
  • Save atnak/f64b8cdb6fe5042cfdc05f7c25411996 to your computer and use it in GitHub Desktop.
Save atnak/f64b8cdb6fe5042cfdc05f7c25411996 to your computer and use it in GitHub Desktop.
Do removals from a java.util.concurrent.ConcurrentMap provide a happens-before guarantee against a retrieval that sees this occurrence?
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import com.google.common.util.concurrent.Uninterruptibles;
public class SomeProgram {
public static void main(String[] args) {
new SomeOperator(1).start();
new SomeOperator(1).start();
new SomeOperator(1).start();
new SomeOperator(1).start();
}
private static class SomeOperator extends Thread {
private static final ConcurrentMap<Integer, Thread> BLOCKING_OPERATORS = new ConcurrentHashMap<>();
private final int id;
public SomeOperator(int id) {
this.id = id;
}
@Override
public void run() {
final Thread previous = BLOCKING_OPERATORS.put(id, this);
if (previous != null) {
previous.interrupt();
Uninterruptibles.joinUninterruptibly(previous);
}
try {
// critical section
} finally {
// doing this breaks synchronization, not because two threads can enter
// the critical section, but because changes made to memory during the
// critical section may not be propagated to the subsequent thread.
//
// on the other hand, not doing this leads to a memory leak from the
// unbounded growing of the map.
//
// suffice to say, this code in its current state is broken.
BLOCKING_OPERATORS.remove(id);
}
}
@Override
public void interrupt() {
super.interrupt();
// fire cancellation mechanism
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment