Có cách nào để thực hiện một loại tham chiếu có giá trị có thể được trao đổi với một nguyên tử khác không?Có thể tạo AtomicReference có thể hoán đổi nguyên tử không?
Trong Java chúng tôi có AtomicReference
có thể được hoán đổi với một biến địa phương nhưng không phải với AtomicReference
khác.
Bạn có thể làm:
AtomicReference r1 = new AtomicReference("hello");
AtomicReference r2 = new AtomicReference("world");
và trao đổi chúng với một sự kết hợp của hai hoạt động:
r1.set(r2.getAndSet(r1.get()));
Nhưng điều này làm cho họ trong tình trạng mâu thuẫn ở giữa, nơi cả hai chứa "hello"
. Thậm chí nếu bạn có thể hoán đổi chúng một cách nguyên tử, bạn vẫn không thể đọc chúng (như một cặp) một cách nguyên tử.
Những gì tôi muốn để có thể làm là:
PairableAtomicReference r1 = new PairableAtomicReference("hello");
PairableAtomicReference r2 = new PairableAtomicReference("world");
AtomicRefPair rp = new AtomicRefPair(r1, r2);
sau đó
Object[] oldVal, newVal;
do {
oldVal = rp.get();
newVal = new Object[] {oldVal[1], oldVal[0]};
} while (! rp.compareAndSet(oldVal, newVal));
để trao đổi các giá trị, và trong chủ đề khác:
AtomicRefPair otherRP = new AtomicRefPair(r1, r2);
System.out.println(Arrays.toString(otherRP.get()));
và chắc chắn rằng đầu ra sẽ là [hello, world]
hoặc [world, hello]
.
Ghi chú:
r1
vàr2
được ghép nối cho hoạt động này, nhưng nó có thể là một sợi độc lập sẽ ghép, nóir1
và mộtr3
- Có (may mà có nghĩa là tôi không thể sử dụng this solution.) sẽ là hàng trăm nghìn tài liệu tham khảo này, vì vậy,
ReentrantLock
toàn cầu sẽ là một nút cổ chai lớn. rp
vàotherRP
không nhất thiết phải được chia sẻ giữa các chuỗi, vì vậy việc chỉ cần khóa chúng sẽ không hoạt động. Chúng có thể là interned, nhưng hồ bơi thực tập sẽ cần sự đồng bộ hóa riêng của nó và đây sẽ là một nút cổ chai khác.- Tôi chỉ tạo nhóm 2 tham chiếu ở đây, nhưng khả năng nhóm 3 trở lên sẽ là tiền thưởng.
Có thể triển khai phiên bản không có khóa AtomicRefPair
không? Tôi có linh cảm rằng nó không phải là, nhưng nếu không thì có lẽ có một bài báo ở đâu đó giải thích tại sao?
liên quan: How do I atomically swap 2 ints in C#?
Có một Thực tập sinh ở ổi, sử dụng ConcurrentHashMap, do đó, tranh chấp có thể nhỏ tùy ý ở mức trung bình. – maaartinus