2013-03-04 25 views
22

Tôi có câu hỏi chung đơn giản về AtomicReference.Bài tập tham chiếu là nguyên tử vậy tại sao sử dụng AtomicReference

Tại sao nên sử dụng AtomicReference nếu phân bổ tham chiếu là nguyên tử trong java?

Ngoài ra, tôi muốn hỏi xem liệu xác nhận tham chiếu có phải là nguyên tử trong các máy ảo 64 bit không?

Chúng ta có cần biến động để có nguyên tử tham chiếu nguyên tử không?

Trả lời

18

câu trả lời trước của tôi là không chính xác, như được giải thích trong các bình luận của juancn:

Đó là sự khác biệt giữa Atomic* lớp và truy cập dễ bay hơi. Phân công tham chiếu là nguyên tử chỉ theo nghĩa là không có từ nào xé có thể xảy ra, nhưng không có khả năng hiển thị hoặc đảm bảo sắp xếp lại. Java đảm bảo viết nguyên tử theo nghĩa hạn chế này cho tất cả các kiểu nguyên thủy và các tham chiếu nhưng không cho dài/đôi (mặc dù trong các máy ảo 64 bit, tôi nghĩ chúng luôn là nguyên tử).

câu trả lời trước

Nó là cần thiết, chủ yếu là cho compareAndSetgetAndSet phương pháp. Bạn không thể làm điều này một cách nguyên tử nếu không (2 thao tác là cần thiết).

+2

+1 đó chính xác là lý do cho tất cả các lớp 'Nguyên tử ... '. –

+1

@JimGarrison không chính xác. các bài tập dài/float/double không phải là nguyên tử. Nó sẽ gán hai từ vào địa chỉ được gán theo thứ tự tùy ý (bạn sẽ cần tìm kiếm thông tin về mô hình bộ nhớ java). Nếu bạn có hai chủ đề cạnh tranh để viết giá trị cho địa chỉ đó, thì bạn có thể nhận được một từ bắt nguồn từ chuỗi 1 và sau đó là từ thứ hai bắt nguồn từ chuỗi 2, dẫn đến giá trị rác – searchengine27

+3

* Có thể được chỉ định trong một thứ tự tùy ý. Nhiều nền tảng phần cứng hỗ trợ độ rộng từ 64 bit. Và trên lưu ý đó, điều này chỉ áp dụng cho dài và gấp đôi. Không nổi, rộng 32 bit. –

21

Tại sao sử dụng AtomicReference nếu phân bổ tham chiếu là nguyên tử trong java?

Bạn cần khi quyết định tạo giá trị mới dựa trên giá trị trước đó của tham chiếu. Ví dụ: khi triển khai một số LinkedList như cấu trúc dữ liệu, bạn không thể đặt đầu cho nút mới có liên quan đến nút trước đó. Trong thời gian giữa việc đọc các nút trước đó và thiết lập đầu đến một cái mới một số chủ đề khác có thể đồng thời cập nhật giá trị tham chiếu đầu. Nếu chủ đề của chúng tôi không nhận thức được sự thay đổi này, nó sẽ bị mất.

Chúng ta có cần biến động để có nguyên tử tham chiếu nguyên tử không?

Bản thân hoạt động sẽ được thực hiện nguyên tử trên lõi CPU thực thi nó nhưng không đảm bảo rằng các luồng trên lõi khác sẽ nhận thức được nó trên lần đọc kế tiếp.

+1

Hơn nữa, ghi vào tài liệu tham khảo luôn là nguyên tử, lấy từ JLS: Ghi và đọc tham chiếu luôn là nguyên tử, bất kể chúng được triển khai dưới dạng giá trị 32 bit hay 64 bit. – SakeSushiBig

+0

+1. Tôi nghĩ câu trả lời của bạn là tuyệt vời, nhưng nó sẽ còn tốt hơn nữa để chứng minh cách lớp AtomicReference được đưa vào chơi như thế nào cho ví dụ bạn đã đưa ra. – nhahtdh

+0

Kiểm tra liên kết này: http://stackoverflow.com/questions/31042696/when-does-a-reference-need-to-be-atomic?noredirect=1&lq=1 –

2

Lý do là mặc dù tham chiếu là nguyên tử, nhưng đó là nguyên tử theo nghĩa rất hẹp.

Nếu chủ đề viết tham chiếu không dễ bay hơi, những gì được đảm bảo là các chủ đề khác sẽ thấy toàn bộ ghi hoặc không nhìn thấy nó ở tất cả (không có từ rách/rác).

Nhưng không có thời điểm nào được đảm bảo rằng bất kỳ chủ đề nào khác sẽ thấy nó cũng không phải là chúng sẽ được xem theo cùng thứ tự.

Một AtomicReference cung cấp đảm bảo mạnh hơn rất nhiều (ngoài các hoạt động CAS), về cơ bản chúng hoạt động như dễ bay hơi:

  • Bất kỳ viết đã xảy ra trong chủ đề A trước một ghi dễ bay hơi có thể nhìn thấy trong thread B sau khi đọc dễ bay hơi tiếp theo của biến đó
  • hoạt động dễ bay hơi không thể được sắp xếp lại
Các vấn đề liên quan