Nó được sử dụng ví dụ trong AtomicReference
, nơi mà trước đây trong Java 8, sun.misc.Unsafe
đã được sử dụng:
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);
}
đây con trỏ this
được sử dụng cùng với một trường offset để truy cập lĩnh vực này. Nhưng điều này là không an toàn, vì bù trừ trường này có thể là bất kỳ long
và bạn thực sự có thể truy cập vào một thứ hoàn toàn khác. Tuy nhiên, có những lợi ích hiệu năng khi thực hiện theo cách này (nó yêu cầu máy ảo sử dụng các chỉ dẫn CPU chuyên biệt) và do đó người khác đã sử dụng sun.misc.Unsafe
mặc dù đó là một API nội bộ và không an toàn.
Một phần của mục đích cho VarHandles là thay thế các hoạt động trong sun.misc.Unsafe
bằng cách tương đương an toàn. Đó là quy định tại the JEP:
Xác định một phương tiện tiêu chuẩn để gọi tương đương của nhiều hoạt động java.util.concurrent.atomic và sun.misc.Unsafe ...
Mục tiêu :
sau đây mục tiêu được yêu cầu:
An toàn. Không thể đặt Máy ảo Java trong trạng thái bộ nhớ bị hỏng. Ví dụ, một trường của một đối tượng chỉ có thể được cập nhật với các cá thể có thể chuyển sang kiểu trường hoặc phần tử mảng chỉ có thể được truy cập trong một mảng nếu chỉ mục mảng nằm trong giới hạn mảng.
Tính toàn vẹn. Truy cập vào một trường của một đối tượng theo cùng các quy tắc truy cập như với các mã byte getfield và putfield ngoài ràng buộc rằng một trường cuối cùng của một đối tượng không thể được cập nhật. (Lưu ý: các quy tắc an toàn và toàn vẹn như vậy cũng áp dụng cho MethodHandles cấp quyền truy cập đọc hoặc ghi vào một trường.)
Hiệu suất. Các đặc tính hiệu suất phải giống hoặc tương tự như các hoạt động sun.misc.Unsafe tương đương (cụ thể, mã trình tạo được tạo ra phải gần như giống hệt nhau một số kiểm tra an toàn nhất định không thể gấp lại được).
Tính khả dụng. API phải tốt hơn API sun.misc.Unsafe.
Vì vậy, trong Java 9 những phương pháp giống như thế này:
public final void lazySet(V newValue) {
VALUE.setRelease(this, newValue);
}
public final boolean compareAndSet(V expectedValue, V newValue) {
return VALUE.compareAndSet(this, expectedValue, newValue);
}
đâu VALUE
là một VarHandle
định nghĩa như thế này:
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);
}
}
xử lý Var (hoặc phương pháp xử lý) khá API cấp thấp cho các thao tác phương thức và hoạt động bộ nhớ. Hầu hết mọi người sẽ không bao giờ cần phải sử dụng các API đó. –