Deadlock
From APIDesign
Deadlock can only happen when all four deadlock conditions are satisfied. Yet, deadlocks happen. As a paradox of APIDesign there is just a single solution to avoid them when designing an API:
Never hold a lock when calling a foreign code!
What is a foreign code in this context? Anything written by users of your API. E.g. callbacks, listeners, etc. must not be called under any lock used in your API. The rule is that simple.
It is easy to follow the rule when dealing with listeners - they are just simple callbacks that notify a change - they don't return any value and as such they can be called asynchronously. which is exactly what UI frameworks like AWT or Swing do: they notify the callbacks *later*. Of course, without holding any locks and thus avoiding deadlocks.