Câu hỏi của tôi liên quan xuất bản an toàn giá trị trường trong Java (như được đánh dấu ở đây Java multi-threading & Safe Publication).Xuất bản an toàn khi giá trị được đọc theo các phương thức đã đồng bộ
Theo tôi được biết, một lĩnh vực có thể được đọc một cách an toàn (có nghĩa là truy cập từ nhiều chủ đề sẽ thấy được giá trị đúng) nếu:
- đọc và ghi được đồng bộ hóa trên màn hình cùng một
- lĩnh vực là cuối cùng
- lĩnh vực có nhiều biến động
Nếu hiểu biết của tôi là đúng lớp sau nên không được thread-safe từ giá trị ban đầu được viết mà không có những đặc điểm này. Tuy nhiên tôi thấy khó tin rằng tôi cần phải thực hiện first
volatile
mặc dù chỉ truy cập từ phương thức synchronized
.
public class Foo {
private boolean needsGreeting = true;
public synchronized void greet() {
if (needsGreeting) {
System.out.println("hello");
needsGreeting = false;
}
}
}
Tôi có thiếu gì đó không? Có mã trên đúng không và nếu có thì tại sao? Hoặc là cần thiết trong các trường hợp như vậy để tạo first
volatile
hoặc sử dụng final AtomicBoolean
hoặc một số thứ như thế ngoài để truy cập nó từ phương thức synchronized
.
(Chỉ cần làm rõ, tôi biết, rằng nếu các giá trị ban đầu được viết bằng một phương pháp synchronized
, nó sẽ là thread-safe thậm chí không có từ khóa volatile
.)
"[...] loại này ngụ ý rằng không có cạnh nào xảy ra trước khi kết thúc của một hàm tạo của đối tượng để bắt đầu một phương pháp tùy ý!". "Hàm ý" này không chính xác. – Grodriguez
Ồ, chắc chắn, nó không phải là một ý nghĩa chính thức. Tuy nhiên, thực tế là họ nói rằng kết thúc của hàm tạo xảy ra trước khi bắt đầu phương thức finalizer, chúng ta sẽ nói "gợi ý" rằng điều này có thể không đúng cho các phương thức tùy ý. – aioobe
@aioobe không, đó là chỉ có cho các trường hợp như mã sau đây: 'new SomeObject()', tức là gọi hàm tạo nhưng không lưu trữ tham chiếu. Sau đó, các đối tượng ngay lập tức có thể được thu thập rác và finalizer ngay lập tức có thể được gọi. Câu bạn đang đề cập đến chỉ cần đảm bảo rằng hàm tạo vẫn kết thúc trước khi trình finalizer chạy. –