Skip to content

Commit

Permalink
Save performing volatile set on LazyValue::set/clear
Browse files Browse the repository at this point in the history
  • Loading branch information
franz1981 authored and Sanne committed Jul 13, 2023
1 parent b03e782 commit 0728b0e
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.quarkus.arc.impl;

import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.function.Supplier;

/**
Expand All @@ -8,6 +9,9 @@
*/
public class LazyValue<T> {

private static final AtomicReferenceFieldUpdater<LazyValue, Object> VALUE_UPDATER = AtomicReferenceFieldUpdater
.newUpdater(LazyValue.class, Object.class, "value");

private final Supplier<T> supplier;

private transient volatile T value;
Expand All @@ -22,10 +26,14 @@ public T get() {
return valueCopy;
}
synchronized (this) {
if (value == null) {
value = supplier.get();
valueCopy = value;
if (valueCopy != null) {
return valueCopy;
}
return value;
valueCopy = supplier.get();
// lazySet == setRelease: it ensure safe publication of the instance
VALUE_UPDATER.lazySet(this, valueCopy);
return valueCopy;
}
}

Expand All @@ -34,8 +42,13 @@ public T getIfPresent() {
}

public void clear() {
if (value == null) {
return;
}
synchronized (this) {
value = null;
if (value != null) {
VALUE_UPDATER.lazySet(this, null);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package io.quarkus.qute;

import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
import java.util.function.Supplier;

final class LazyValue<T> {

private static final AtomicReferenceFieldUpdater<LazyValue, Object> VALUE_UPDATER = AtomicReferenceFieldUpdater
.newUpdater(LazyValue.class, Object.class, "value");

private final Supplier<T> supplier;

private transient volatile T value;
Expand All @@ -18,10 +22,14 @@ public T get() {
return valueCopy;
}
synchronized (this) {
if (value == null) {
value = supplier.get();
valueCopy = value;
if (valueCopy != null) {
return valueCopy;
}
return value;
valueCopy = supplier.get();
// lazySet == setRelease: it ensure safe publication of the instance
VALUE_UPDATER.lazySet(this, valueCopy);
return valueCopy;
}
}

Expand All @@ -30,8 +38,13 @@ public T getIfPresent() {
}

public void clear() {
if (value == null) {
return;
}
synchronized (this) {
value = null;
if (value != null) {
VALUE_UPDATER.lazySet(this, null);
}
}
}

Expand Down

0 comments on commit 0728b0e

Please sign in to comment.