square/otto — pull request #16 by johncarl81 (2012-08-03 00:12:16+00:00)
Title: Concurrency when registering Producers and Subscribers

There is a subtle concurrency bug when registering Producers and Subscribers. It seems that if you hit the register method with more than one thread there may be contention in the following blocks:

Producers:
```java
if (producersByType.containsKey(type)) {
throw new IllegalArgumentException("Producer method for type " + type + " already registered.");
}
final EventProducer producer = foundProducers.get(type);
producersByType.put(type, producer);
```
Subscribers:
```java
Set handlers = handlersByType.get(type);\
if (handlers == null) {
handlers = new CopyOnWriteArraySet();
handlersByType.put(type, handlers);
}
```

The fix is to use the putIfAbsent() method available on the ConcurrentHashMap. This is included in the pull request. I've also included the relevant unit test demonstrating the issue. Of course, since these are concurrency bugs the unit tests may respond with false positives.

Also, I did test this on real hardware and was able to make it fail in both cases.

Let me know if you have any questions.