Alibaba Druid Connection Pool: takeLast() AQS Deadlock Makes the Application Unresponsive

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.

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:

Most threads waiting in the dump

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

Druid takeLast waiting on AQS

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.