Skip to content

Commit ea28746

Browse files
committed
fix: Replace synchronized with ReentrantLock in SecurityAspect to avoid virtual thread pinning.
1 parent 3cece03 commit ea28746

1 file changed

Lines changed: 9 additions & 1 deletion

File tree

aop/src/main/java/net/legacy/library/aop/aspect/SecurityAspect.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Map;
2020
import java.util.concurrent.ConcurrentHashMap;
2121
import java.util.concurrent.atomic.AtomicLong;
22+
import java.util.concurrent.locks.ReentrantLock;
2223

2324
/**
2425
* Aspect for securing method execution with authentication and authorization.
@@ -194,7 +195,8 @@ private void checkRateLimit(Secured secured, SecurityContext context) {
194195
long currentTime = System.currentTimeMillis();
195196
long windowStart = currentTime - (secured.timeWindow() * 1000L);
196197

197-
synchronized (state) {
198+
state.lock.lock();
199+
try {
198200
// Clean old requests
199201
state.requestTimes.removeIf(time -> time < windowStart);
200202

@@ -205,6 +207,8 @@ private void checkRateLimit(Secured secured, SecurityContext context) {
205207

206208
// Add current request
207209
state.requestTimes.add(currentTime);
210+
} finally {
211+
state.lock.unlock();
208212
}
209213
}
210214

@@ -287,9 +291,13 @@ private String getUserAgent() {
287291

288292
/**
289293
* Rate limit state for tracking request timestamps.
294+
*
295+
* <p>Uses {@link ReentrantLock} instead of {@code synchronized} to avoid
296+
* virtual thread pinning in Java 21.
290297
*/
291298
private static class RateLimitState {
292299

300+
private final ReentrantLock lock = new ReentrantLock();
293301
private final java.util.List<Long> requestTimes = new java.util.ArrayList<>();
294302

295303
}

0 commit comments

Comments
 (0)