Skip to content

Instantly share code, notes, and snippets.

@alcatrazEscapee
Created November 13, 2021 03:05
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alcatrazEscapee/cc25cd3ba257e8624d762ff491c9d6bb to your computer and use it in GitHub Desktop.
Save alcatrazEscapee/cc25cd3ba257e8624d762ff491c9d6bb to your computer and use it in GitHub Desktop.
Race condition involving `BiMap.put` and `BiMap.get`, where `get` returns `null` despite no null ever being present in the map.
package bi_map_race_condition;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
public class BiMapRaceCondition
{
public static void main(String[] args)
{
// The map in question uses registry keys, but those are ultimately equals-dependent on strings
// Pre-load it a bit
final BiMap<String, Object> map = HashBiMap.create();
for (int i = 0; i < 100; i++)
{
map.put("key:" + i, new Object());
}
final String key = "special key";
map.put(key, new Object());
// We want to see if concurrent calls to map#put can cause map#get to return null
final long start = System.currentTimeMillis();
final ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(() -> {
while (System.currentTimeMillis() < start + 1000)
{
map.put(key, new Object());
}
});
while (System.currentTimeMillis() < start + 1000)
{
final Object retrievedObject = map.get(key);
if (retrievedObject == null)
{
System.out.println("Race condition!");
}
}
executor.shutdown();
}
}
@bryan-hoang
Copy link

Interesting!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment