Bên dưới, AtomicInteger và AtomicIntegerArray thường sử dụng cùng một API mức thấp để thực hiện đọc, viết và các hoạt động CAS khác. (Ví dụ, OpenSDK 7 sử dụng sun.misc.Unsafe
để thực hiện các hoạt động CAS trong cả hai lớp.) Vì vậy, có rất ít lợi ích về hiệu suất khi sử dụng AtomicInteger []. Như bạn đã lưu ý, việc sử dụng AtomicIntegerArray không có lợi thế đáng kể về bộ nhớ.
Trên một lưu ý thực tế, việc sử dụng sau này giải phóng bạn khỏi việc phải xây dựng tất cả các phiên bản AtomicInteger của bạn. Hãy nhớ rằng bạn không thể phân bổ một cách ngây thơ một cách ngây thơ vì lý do đồng thời; bạn sẽ phải phân bổ trước hoặc sử dụng một số cơ chế xuất bản an toàn. Vì vậy, ngoài lợi thế bộ nhớ, mã của bạn còn sạch hơn.
On Tương tự, nếu bạn có một loạt các đối tượng với các thành viên AtomicInteger, ví dụ:
class ReadCounter {
private final String _fileName;
private final AtomicInteger _readCount;
...
}
private final Map<String, ReadCounter> _counterByName = ...;
Sau đó, bạn có thể đạt được những cải thiện bộ nhớ tương tự bằng cách mô hình hóa các biến thành viên _readCount
như một volatile int
và sử dụng AtomicIntegerFieldUpdater
.
Nguồn
2009-03-28 16:39:29
Ai quan tâm đến kiểm tra giới hạn? Nếu bạn nhìn vào mã nguồn (rõ ràng), ví dụ, getAndSet nó tính toán địa chỉ cho cả get và compareAndSet (mặc dù tệ hơn thế này, hầu hết các bộ vi xử lý có thể thực hiện get-and-set mà không có cas). –
tnx (không thấy đoạn thứ hai của bạn ở đó) Vì vậy, có thể không tốt để tạo tất cả các đối tượng cùng một lúc? (hoặc với một số thứ tự ngẫu nhiên?) – Sarmun
(Tôi đã chỉnh sửa nhanh.) Tạo đối tượng tại các thời điểm khác nhau sẽ không giúp ích vì GC sẽ sắp xếp lại chúng. Một trong các lớp trong java.util.concurrent đi xa hơn để thêm nhiều padding (trong các phiên bản gần đây). Nó sẽ dễ dàng hơn và rõ ràng hơn để thêm các phần tử đệm vào AtomicIntegerArray, chỉ cần dịch chuyển sang trái. –