From e6a664b0b60dabd4ca3f2d3a174f4d5038a45e49 Mon Sep 17 00:00:00 2001 From: Koziolek Date: Fri, 18 Oct 2024 19:35:35 +0200 Subject: [PATCH 1/2] feat: Replace synchronized by Lock in FutureImpl --- .../java/io/vavr/concurrent/FutureImpl.java | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/vavr/src/main/java/io/vavr/concurrent/FutureImpl.java b/vavr/src/main/java/io/vavr/concurrent/FutureImpl.java index 57bd243ae..6f036abba 100644 --- a/vavr/src/main/java/io/vavr/concurrent/FutureImpl.java +++ b/vavr/src/main/java/io/vavr/concurrent/FutureImpl.java @@ -25,7 +25,9 @@ import java.util.Objects; import java.util.concurrent.*; +import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.LockSupport; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.Consumer; /** @@ -45,7 +47,7 @@ final class FutureImpl implements Future { /** * Used to synchronize state changes. */ - private final Object lock = new Object(); + private final Lock lock = new ReentrantLock(); /** * Indicates if this Future is cancelled @@ -88,7 +90,8 @@ final class FutureImpl implements Future { // single constructor private FutureImpl(Executor executor, Option> value, Queue>> actions, Queue waiters, Computation computation) { this.executor = executor; - synchronized (lock) { + lock.lock(); + try { this.cancelled = false; this.value = value; this.actions = actions; @@ -98,6 +101,8 @@ private FutureImpl(Executor executor, Option> value, Queue onComplete(Consumer> action) { if (isCompleted()) { perform(action); } else { - synchronized (lock) { + lock.lock(); + try { if (isCompleted()) { perform(action); } else { actions = actions.enqueue((Consumer>) action); } + } finally { + lock.unlock(); } } return this; @@ -362,7 +379,8 @@ boolean tryComplete(Try value) { final Queue>> actions; final Queue waiters; // it is essential to make the completed state public *before* performing the actions - synchronized (lock) { + lock.lock(); + try { if (isCompleted()) { actions = null; waiters = null; @@ -374,6 +392,8 @@ boolean tryComplete(Try value) { this.waiters = null; this.thread = null; } + } finally { + lock.unlock(); } if (waiters != null) { waiters.forEach(this::unlock); From ec314afd99fdcfec65c5fe72076eeed2308bdc1b Mon Sep 17 00:00:00 2001 From: Koziolek Date: Fri, 18 Oct 2024 19:38:27 +0200 Subject: [PATCH 2/2] feat: move Lock initialization to constructor --- vavr/src/main/java/io/vavr/concurrent/FutureImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vavr/src/main/java/io/vavr/concurrent/FutureImpl.java b/vavr/src/main/java/io/vavr/concurrent/FutureImpl.java index 6f036abba..f56b2458c 100644 --- a/vavr/src/main/java/io/vavr/concurrent/FutureImpl.java +++ b/vavr/src/main/java/io/vavr/concurrent/FutureImpl.java @@ -47,7 +47,7 @@ final class FutureImpl implements Future { /** * Used to synchronize state changes. */ - private final Lock lock = new ReentrantLock(); + private final Lock lock; /** * Indicates if this Future is cancelled @@ -89,6 +89,7 @@ final class FutureImpl implements Future { // single constructor private FutureImpl(Executor executor, Option> value, Queue>> actions, Queue waiters, Computation computation) { + this.lock = new ReentrantLock(); this.executor = executor; lock.lock(); try {