Skip to content

Commit 7ac3cd9

Browse files
committed
Update Lazy.java to use j.u.c.lock
Use Lock rather than object mutexes to enable future loom support to function correctly. Signed-off-by: ascopes <73482956+ascopes@users.noreply.github.com>
1 parent 512a3bd commit 7ac3cd9

File tree

1 file changed

+21
-8
lines changed
  • java-compiler-testing/src/main/java/io/github/ascopes/jct/utils

1 file changed

+21
-8
lines changed

java-compiler-testing/src/main/java/io/github/ascopes/jct/utils/Lazy.java

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
package io.github.ascopes.jct.utils;
1717

18+
import java.util.concurrent.locks.Lock;
19+
import java.util.concurrent.locks.ReentrantLock;
1820
import java.util.Objects;
1921
import java.util.function.Supplier;
2022
import org.apiguardian.api.API;
@@ -33,8 +35,7 @@
3335
* <p>This descriptor is thread-safe. No guarantees are made about the thread-safety of the
3436
* internally stored data, nor the initializer supplier.
3537
*
36-
* <p>This descriptor currently does not support virtual threads. Any synchronization will
37-
* occur on the physical thread level.
38+
* <p>This descriptor supports working with Loom virtual threads correctly.
3839
*
3940
* @param <T> the type of lazy value to return when accessed.
4041
* @author Ashley Scopes
@@ -44,7 +45,7 @@
4445
public final class Lazy<T> {
4546

4647
private final Supplier<T> initializer;
47-
private final Object lock;
48+
private final Lock lock;
4849
private volatile @Nullable T data;
4950

5051
/**
@@ -54,7 +55,7 @@ public final class Lazy<T> {
5455
*/
5556
public Lazy(Supplier<T> initializer) {
5657
this.initializer = Objects.requireNonNull(initializer, "initializer must not be null");
57-
lock = new Object();
58+
lock = new ReentrantLock();
5859
data = null;
5960
}
6061

@@ -65,10 +66,13 @@ public String toString() {
6566

6667
// Synchronize to prevent a race condition between reading
6768
// the data and reading the "initialized" flag.
68-
synchronized (lock) {
69+
lock.lock();
70+
try {
6971
repr = new ToStringBuilder(this)
7072
.attribute("data", data)
7173
.toString();
74+
} finally {
75+
lock.unlock();
7276
}
7377

7478
return repr;
@@ -81,10 +85,13 @@ public String toString() {
8185
*/
8286
public T access() {
8387
if (data == null) {
84-
synchronized (lock) {
88+
lock.lock();
89+
try {
8590
if (data == null) {
8691
data = initializer.get();
8792
}
93+
} finally {
94+
lock.unlock();
8895
}
8996
}
9097

@@ -101,8 +108,11 @@ public T access() {
101108
*/
102109
public void destroy() {
103110
if (data != null) {
104-
synchronized (lock) {
111+
lock.lock();
112+
try {
105113
data = null;
114+
} finally {
115+
lock.unlock();
106116
}
107117
}
108118
}
@@ -120,10 +130,13 @@ public <E extends Throwable> Lazy<T> ifInitialized(
120130
ThrowingConsumer<? super T, ? extends E> consumer
121131
) throws E {
122132
if (data != null) {
123-
synchronized (lock) {
133+
lock.lock();
134+
try {
124135
if (data != null) {
125136
consumer.consume(data);
126137
}
138+
} finally {
139+
lock.unlock();
127140
}
128141
}
129142

0 commit comments

Comments
 (0)