2011-07-19 9 views
5

Tất cả ví dụ tôi đã tìm thấy nói về khả năng hiển thị là ví dụ với kiểu nguyên thủy. Những gì tôi muốn biết là: nếu một đối tượng mới trong heap, khi một thread gọi phương thức của nó để thay đổi trạng thái của nó, không khóa hoặc đồng bộ hóa, luồng khác sẽ thấy thay đổi này? Hãy tưởng tượng một đối tượng Java.Colletion, một thread gọi phương thức của nó add()gây nhầm lẫn về khả năng hiển thị biến thể của chuỗi java

Có người nói cho đối tượng trong đống vẫn có vấn đề tầm nhìn, nhưng JLS nói: 17.4.1 Shared Variables Memory có thể được chia sẻ giữa các chủ đề được gọi là bộ nhớ chia sẻ hoặc bộ nhớ heap.

http://www.artima.com/insidejvm/ed2/jvm2.html cho biết: Ngăn xếp Java của một luồng lưu trữ trạng thái lời gọi phương thức Java (không phải nguyên gốc) cho chuỗi. Trạng thái của một lời gọi phương thức Java bao gồm các biến cục bộ của nó, các tham số mà nó được viện dẫn, giá trị trả về của nó (nếu có) và các phép tính trung gian.

Vì vậy, tôi nghĩ, JVM sẽ không sao chép một đối tượng trong bộ đệm CPU vào bộ đệm. Nếu điều này là đúng, đối tượng trong heap sẽ không có vấn đề về khả năng hiển thị, bởi vì luồng chỉ tham chiếu đến đối tượng trong heap.

BTW Giả sử có sự cố đồng thời khi một chuỗi gọi .add(). Trong quá trình bình thường, thay đổi phải bảo vệ bằng khóa, vì vậy vấn đề này không phải là vấn đề. Nhưng tôi chỉ muốn biết :)

+3

đọc phần 'Hiển thị' [ở đây] (http://gee.cs.oswego.edu/dl/cpj/jmm.html) –

+1

Cảm ơn, tôi nghĩ đây là câu trả lời cuối cùng, mọi chi tiết đã được nói – jean

Trả lời

2

Bạn vẫn có thể thực hiện đồng bộ hóa bộ nhớ mà không synchronized nếu bạn có volatile, biến nguyên tử, hoặc container đồng thời khác cung cấp xảy ra-trước ngữ nghĩa. Tuy nhiên, nếu bạn không làm những điều đó, thì không có gì được đảm bảo liên quan đến khả năng hiển thị bộ nhớ.

Trong trường hợp cụ thể của bạn, nếu bạn muốn gọi add() trên một thùng chứa trong một chuỗi và có thể nhìn thấy nó trong một thùng khác mà không khóa rõ ràng, thì điều này sẽ chỉ hoạt động nếu vùng chứa là đồng thời (ví dụ: một trong các trong gói java.util.concurrent) hoặc một gói được đồng bộ hóa (ví dụ: Collections.synchronizedList).

3

Câu trả lời là "không, chủ đề khác sẽ không nhất thiết phải xem thay đổi đối với Bộ sưu tập", vì (hầu hết) Bộ sưu tập tiêu chuẩn không an toàn chủ đề - nghĩa là chúng không được xuất bản an toàn trạng thái của họ. (Chủ đề khác có thể, hoặc có thể không thấy thay đổi).

Đó là lý do tại sao java.util.concurrent package được tạo - nó cung cấp triển khai an toàn thread của java.util.Collections.