10

Nếu tôi truy cập một đối tượng bên trong một phương thức được đồng bộ hóa hoặc khối được đồng bộ hóa, tất cả đối tượng trong phần tử truy cập đó cũng được đồng bộ hóa không?Đồng bộ hóa của Java có cập nhật bộ đệm ẩn hoàn chỉnh hay chỉ đối tượng tôi đã đồng bộ hóa không?

Hãy tưởng tượng có một đối tượng Queue có phương thức add()take() được đồng bộ hóa, chấp nhận và phân phát đối tượng phức tạp Thing. Thing có rất nhiều danh sách với các đối tượng khác nhau trong đó.

Bây giờ, chủ đề hình ảnh Before tạo Thing và đặt một số đối tượng hiện có vào Thing, sửa đổi một số đối tượng này, v.v. Chủ đề Before thêm Thing đến Queue. Chủ đề sau bit After mất Thing từ Queue.

CÂU HỎI: Thing và tất cả các con/subobject của nó có cùng trạng thái như Before để chúng ở trong đó không? Ngay cả khi chuỗi After có thể hoạt động trên một trong các phần tử con này sớm hơn một chút? Bởi vì tôi hình ảnh bộ vi xử lý cho chủ đề After vẫn có thể có một số thông tin được lưu trong bộ nhớ cache trên subelement đó (địa chỉ của subobject đó vẫn giống nhau). Tất cả các công cụ được lưu trong bộ nhớ cache này sẽ bị vô hiệu hóa chỉ khi truy cập đối tượng cha Thing theo cách được đồng bộ hóa?

Vui lòng không đưa ra câu trả lời như sử dụng lib đồng thời, v.v. Tôi muốn hiểu điều gì đang diễn ra.

Trả lời

7

Khái niệm quan trọng trong mô hình bộ nhớ của Java là happens-before order. Kết quả ghi các hành động mà xảy ra trước khi tác vụ đọc hiển thị cho các tác vụ đã đọc này. Các kết quả khác có thể hoặc không thể nhìn thấy được.

Các xảy ra-trước trật tự được gây ra bởi trật tự đồng bộ hóa các hành động giữa các chủ đề, và do tự nhiên trật tự của các hành động trong các chủ đề cá nhân.

Nếu bạn ở Before đồng bộ hóa trên một đối tượng (ví dụ:Queue) và thực hiện tất cả các thao tác của bạn Thing và các "đối tượng con" bên trong hoặc trước khối đồng bộ hóa này và After được đồng bộ hóa trên cùng một Queue và đọc các đối tượng này trong hoặc sau khối được đồng bộ hóa, sau đó tất cả những thay đổi đó hiển thị với After.

9

Nếu chủ đề sửa đổi biến, chuỗi khác không được bảo đảm để xem thay đổi ngoại trừ trong các trường hợp sau (tốt, ít nhất trong các trường hợp sau; tôi không chắc chắn 100% nếu có nhiều hơn):

  • luồng sửa đổi để lại một khối hoặc phương thức được đồng bộ hóa; điều này gây ra sự tuôn ra của bộ đệm luồng (tương tự như một luồng đi vào khối đồng bộ hoặc phương thức làm mới) - đây là điều xảy ra trong trường hợp của bạn
  • biến được sửa đổi được khai báo volatile hoặc nó là một trong các biến nguyên tử từ java.util.concurrent.atomic
  • kết thúc chủ đề sửa đổi (điều này cũng gây ra một tuôn ra, tương tự như vậy khi bắt đầu một chủ đề gây ra một refresh)

vì vậy, nếu bạn đồng bộ hóa như bạn giải thích, chủ đề khác sẽ thấy tất cả những thay đổi.

+1

vâng tôi biết điều đó, nhưng đó không phải là câu hỏi của tôi :-) Đồng bộ hóa cũng phải ảnh hưởng đến bộ nhớ cache của bộ xử lý, do đó các thay đổi được xóa vào bộ nhớ chung, đó là câu hỏi của tôi. Tôi biết rằng nếu bạn truy cập một tài liệu tham khảo mà không đi qua một khối đồng bộ từ các chủ đề song song mulitple nó sẽ được tất cả mọi thứ sai lầm. Nhưng điều này là nhiều hơn về việc chuyển các công cụ từ một luồng này sang luồng khác và đảm bảo rằng datastrucuture vẫn chính xác. Hiểu những gì tôi nói không? –

+1

Xem câu trả lời của Paulo. Chặn các luồng chỉ là một khía cạnh của việc đồng bộ hóa, mối quan hệ xảy ra trước đó (xóa bộ nhớ đệm) là quan trọng nếu không nhiều hơn. Nó cũng phức tạp hơn rất nhiều để hiểu và các API không rõ ràng về việc xảy ra trước đây (ví dụ, tôi nghĩ SwingUtilities.invokeLater đã kích thích một sự kiện xảy ra trước đó, nhưng tôi không chắc chắn 100%). Tôi khuyên bạn nên sử dụng Java Concurrency in Practice từ Goetz et al. Họ đặt rất nhiều nhấn mạnh vào xảy ra trước đây. – toto2

+0

Cảm ơn bạn đã downvoting mà không có lời giải thích ... @ Franz: Tôi không hỏi rằng bạn đang hỏi về mô hình bộ nhớ. Hãy để tôi xem xét lại câu trả lời của tôi. – musiKk

Các vấn đề liên quan