:
public final void lazySet(V newValue) {
unsafe.putOrderedObject(this, valueOffset, newValue);
}
public final boolean compareAndSet(V expect, V update) {
return unsafe.compareAndSwapObject(this, valueOffset, expect, update);
}
ここthis
ポインタがフィールドにアクセスするためのオフセットフィールドと一緒に使用されます。しかし、このフィールドのオフセットは任意のlong
になる可能性があり、実際にはまったく異なるものにアクセスしている可能性があるため、これは安全ではありません。ただし、このようにするとパフォーマンスのメリットがあります(VMに特殊なCPU命令を使用するように指示します)。そのため他の人がsun.misc.Unsafe
を使用しています。
VarHandlesの目的の一部は、sun.misc.Unsafe
の操作を安全な同等物に置き換えることです。どのthe JEPに記載されています
...
目標のさまざまなは、java.util.concurrent.atomicとsun.misc.Unsafe事業の当量を呼び出すための標準的な手段を定義します。 :
以下が要求される目標:
安全性。 Java仮想マシンを破損したメモリ状態にすることはできません。たとえば、オブジェクトのフィールドは、フィールド型にキャスト可能なインスタンスでのみ更新することができます。または、配列インデックスが配列境界内にある場合、配列要素は配列内でのみアクセスできます。
インテグリティ。オブジェクトのフィールドへのアクセスは、オブジェクトの最終フィールドを更新できないという制約に加えて、getfieldおよびputfieldのバイトコードと同じアクセス規則に従います。 (注:このような安全性と完全性の規則は、フィールドへの読み取りまたは書き込みアクセスを与えるMethodHandlesにも適用されます)。
パフォーマンス。パフォーマンスの特性は、同等のsun.misc.Unsafe操作と同じである必要があります(具体的には、生成されたアセンブラコードは、折りたたむことができない特定の安全性チェックをモジュロにする必要があります)。
使いやすさ。 APIはsun.misc.Unsafe APIよりも優れている必要があります。
だから、Javaの9にこれらのメソッドは次のようになります。VALUE
はこのようVarHandle
定義され
public final void lazySet(V newValue) {
VALUE.setRelease(this, newValue);
}
public final boolean compareAndSet(V expectedValue, V newValue) {
return VALUE.compareAndSet(this, expectedValue, newValue);
}
:
private static final VarHandle VALUE;
static {
try {
MethodHandles.Lookup l = MethodHandles.lookup();
VALUE = l.findVarHandle(AtomicReference.class, "value", Object.class);
} catch (ReflectiveOperationException e) {
throw new Error(e);
}
}
ヴァールハンドル(またはメソッドハンドル)かなりありますメソッド呼出しとメモリ操作のための低レベルのAPIほとんどの人は、これらのAPIを使用する必要はありません。 –