12
12
import static io .art .core .factory .ListFactory .*;
13
13
import static io .art .core .factory .QueueFactory .*;
14
14
import static java .util .Objects .*;
15
+
16
+ import java .lang .invoke .MethodHandles ;
17
+ import java .lang .invoke .VarHandle ;
15
18
import java .util .*;
16
19
import java .util .function .*;
17
20
18
21
@ RequiredArgsConstructor
19
22
@ SuppressWarnings (SUN_API )
20
23
public class DisposableProperty <T > implements Supplier <T > {
21
24
private static final Object UNINITIALIZED = new Object ();
22
- private static final sun .misc .Unsafe UNSAFE = UnsafeAccess .UNSAFE ;
23
- private static final long VALUE_OFFSET ;
25
+ private static final VarHandle VALUE_HANDLE ;
24
26
25
27
static {
26
28
try {
27
- VALUE_OFFSET = UNSAFE .objectFieldOffset (DisposableProperty .class .getDeclaredField (VALUE_FIELD_NAME ));
29
+ MethodHandles .Lookup lookup = MethodHandles .lookup ();
30
+ VALUE_HANDLE = lookup .findVarHandle (DisposableProperty .class , VALUE_FIELD_NAME , Object .class );
28
31
} catch (Throwable throwable ) {
29
32
throw new InternalRuntimeException (throwable );
30
33
}
@@ -77,13 +80,13 @@ public void dispose() {
77
80
if (current == UNINITIALIZED ) {
78
81
return ;
79
82
}
80
- current = cast (UNSAFE . getObjectVolatile (this , VALUE_OFFSET ));
83
+ current = cast (VALUE_HANDLE . getVolatile (this ));
81
84
if (current == UNINITIALIZED ) {
82
85
return ;
83
86
}
84
87
85
88
final T currentValue = current ;
86
- if (UNSAFE . compareAndSwapObject (this , VALUE_OFFSET , current , UNINITIALIZED )) {
89
+ if (VALUE_HANDLE . compareAndSet (this , current , UNINITIALIZED )) {
87
90
apply (disposeConsumers , consumers -> consumers .forEach (consumer -> consumer .accept (currentValue )));
88
91
}
89
92
}
@@ -92,12 +95,12 @@ public void dispose() {
92
95
public T get () {
93
96
T localValue = value ;
94
97
if (localValue == UNINITIALIZED ) {
95
- localValue = cast (UNSAFE . getObjectVolatile (this , VALUE_OFFSET ));
98
+ localValue = cast (VALUE_HANDLE . getVolatile (this ));
96
99
if (localValue == UNINITIALIZED ) {
97
100
T loaded = orThrow (loader .get (), new InternalRuntimeException (PROPERTY_VALUE_IS_NULL ));
98
- localValue = UNSAFE . compareAndSwapObject (this , VALUE_OFFSET , UNINITIALIZED , loaded )
101
+ localValue = VALUE_HANDLE . compareAndSet (this , UNINITIALIZED , loaded )
99
102
? loaded
100
- : cast (UNSAFE . getObjectVolatile (this , VALUE_OFFSET ));
103
+ : cast (VALUE_HANDLE . getVolatile (this ));
101
104
apply (creationConsumers , consumers -> erase (consumers , consumer -> consumer .accept (loaded )));
102
105
apply (initializationConsumers , consumers -> consumers .forEach (consumer -> consumer .accept (loaded )));
103
106
}
0 commit comments