A colleague on site reported that my application would periodically freeze with no response and no error logs — API requests just hung waiting. After they sent me a thread dump, I saw most threads in WAITING, stuck in com.alibaba.druid.pool.DruidDataSource.takeLast(). Solution first, root cause after.
The solution
Set the maxWait parameter in your Alibaba Druid configuration.
That’s it. Yes, really that simple — if you only want the problem fixed, go try it. If you want to know why, like I did, read on.
Investigation
I had the colleague export the thread dump. Most threads were in WAITING:

Looking into the stack, they were stuck waiting inside com.alibaba.druid.pool.DruidDataSource.takeLast():

I was on Druid 1.2.17. Searching the source for that method: https://github.com/alibaba/druid/blob/1.2.17/core/src/main/java/com/alibaba/druid/pool/DruidDataSource.java#L2289
Who calls it? Exactly one place: https://github.com/alibaba/druid/blob/1.2.17/core/src/main/java/com/alibaba/druid/pool/DruidDataSource.java#L1758-L1762
The logic: when maxWait > 0, it executes pollLast; otherwise it executes takeLast — and deadlocks. And the default value of maxWait is -1:
https://github.com/alibaba/druid/blob/1.2.17/core/src/main/java/com/alibaba/druid/pool/DruidAbstractDataSource.java#L69
I checked — indeed, I hadn’t configured it. After adding maxWait to the config file, the freezes never came back.
What is maxWait?
maxWait: the maximum time to wait when borrowing a connection from the pool, in milliseconds. Default is -1, meaning wait forever.
With the default -1, when the pool has no connections left, the application just waits. And waits. And waits…
In newer versions this appears to have been fixed — there’s a commit from January 23, 2024: https://github.com/alibaba/druid/commit/6ec6c006993824ad9a068e3444d770969c4cc410 The code has changed; feel free to dig in further.
