From 4b94198b10b527991ecdedfd384272e7d82904b4 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Tue, 10 Dec 2024 09:51:11 +0300 Subject: [PATCH] refactoring --- .../org/redisson/cache/FastRemovalQueue.java | 11 ++++- .../client/handler/CommandsQueue.java | 2 +- .../main/java/org/redisson/misc/SpinLock.java | 44 ++++++++++++++++++- .../java/org/redisson/misc/SpinLockTest.java | 4 +- 4 files changed, 55 insertions(+), 6 deletions(-) diff --git a/redisson/src/main/java/org/redisson/cache/FastRemovalQueue.java b/redisson/src/main/java/org/redisson/cache/FastRemovalQueue.java index bcaa58fe1..ebcc38a29 100644 --- a/redisson/src/main/java/org/redisson/cache/FastRemovalQueue.java +++ b/redisson/src/main/java/org/redisson/cache/FastRemovalQueue.java @@ -56,6 +56,10 @@ public final class FastRemovalQueue { return false; } + public int size() { + return index.size(); + } + public E poll() { Node node = list.removeFirst(); if (node != null) { @@ -122,7 +126,7 @@ public final class FastRemovalQueue { } public boolean remove(Node node) { - return lock.execute(() -> { + Boolean r = lock.execute(() -> { if (node.isDeleted()) { return false; } @@ -131,6 +135,7 @@ public final class FastRemovalQueue { node.setDeleted(); return true; }); + return Boolean.TRUE.equals(r); } private void removeNode(Node node) { @@ -152,6 +157,10 @@ public final class FastRemovalQueue { public void moveToTail(Node node) { lock.execute(() -> { + if (node.isDeleted()) { + return; + } + removeNode(node); node.prev = null; diff --git a/redisson/src/main/java/org/redisson/client/handler/CommandsQueue.java b/redisson/src/main/java/org/redisson/client/handler/CommandsQueue.java index f925d69d1..42daac768 100644 --- a/redisson/src/main/java/org/redisson/client/handler/CommandsQueue.java +++ b/redisson/src/main/java/org/redisson/client/handler/CommandsQueue.java @@ -80,7 +80,7 @@ public class CommandsQueue extends ChannelDuplexHandler { } }); - lock.execute(() -> { + lock.executeInterruptibly(() -> { try { queue.add(holder); ctx.writeAndFlush(data, holder.getChannelPromise()); diff --git a/redisson/src/main/java/org/redisson/misc/SpinLock.java b/redisson/src/main/java/org/redisson/misc/SpinLock.java index bb3b88d4d..d0b32d659 100644 --- a/redisson/src/main/java/org/redisson/misc/SpinLock.java +++ b/redisson/src/main/java/org/redisson/misc/SpinLock.java @@ -16,6 +16,7 @@ package org.redisson.misc; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Supplier; /** * @@ -29,6 +30,16 @@ public final class SpinLock { private final int spinLimit = 7000; private int nestedLevel; + private final boolean reentrant; + + public SpinLock() { + this(true); + } + + public SpinLock(boolean reentrant) { + this.reentrant = reentrant; + } + private void lockInterruptibly() throws InterruptedException { int spins = 0; while (true) { @@ -36,7 +47,8 @@ public final class SpinLock { throw new InterruptedException(); } - if (acquired.get() == Thread.currentThread()) { + if (reentrant + && acquired.get() == Thread.currentThread()) { nestedLevel++; return; } else if (acquired.get() == null @@ -60,7 +72,35 @@ public final class SpinLock { } } - public void execute(Runnable r) throws InterruptedException { + public void execute(Runnable r) { + try { + lockInterruptibly(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return; + } + try { + r.run(); + } finally { + unlock(); + } + } + + public T execute(Supplier r) { + try { + lockInterruptibly(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return null; + } + try { + return r.get(); + } finally { + unlock(); + } + } + + public void executeInterruptibly(Runnable r) throws InterruptedException { lockInterruptibly(); try { r.run(); diff --git a/redisson/src/test/java/org/redisson/misc/SpinLockTest.java b/redisson/src/test/java/org/redisson/misc/SpinLockTest.java index 99fecfc8a..0983a15ed 100644 --- a/redisson/src/test/java/org/redisson/misc/SpinLockTest.java +++ b/redisson/src/test/java/org/redisson/misc/SpinLockTest.java @@ -11,9 +11,9 @@ public class SpinLockTest { public void test() throws InterruptedException { SpinLock l = new SpinLock(); CountDownLatch latch = new CountDownLatch(1); - l.execute(() -> { + l.executeInterruptibly(() -> { try { - l.execute(() -> { + l.executeInterruptibly(() -> { latch.countDown(); }); } catch (InterruptedException e) {