Câu hỏi liên quan đến JMM và ngữ nghĩa liên quan đến các trường dễ bay hơi được ghi vào khối được đồng bộ hóa, nhưng đọc không đồng bộ.Sự cần thiết của mảng biến động viết trong khi trong khối đồng bộ
Trong phiên bản ban đầu của mã bên dưới, tôi đã không đồng bộ hóa quyền truy cập vì nó không cần thiết cho các yêu cầu trước đó (và lạm dụng tự gán this.cache = this.cache đảm bảo ngữ nghĩa viết dễ bay hơi). Một số yêu cầu đã thay đổi, cần phải đồng bộ hóa để đảm bảo rằng các bản cập nhật trùng lặp không được gửi đi. Câu hỏi tôi có là khối đồng bộ hóa có ngăn cản việc gán tự động của trường biến động không?
// Cache of byte[] data by row and column.
private volatile byte[][][] cache;
public byte[] getData(int row, int col)
{
return cache[row][col];
}
public void updateData(int row, int col, byte[] data)
{
synchronized(cache)
{
if (!Arrays.equals(data,cache[row][col]))
{
cache[row][col] = data;
// Volatile write.
// The below line is intentional to ensure a volatile write is
// made to the array, since access via getData is unsynchronized.
this.cache = this.cache;
// Notification code removed
// (mentioning it since it is the reason for synchronizing).
}
}
}
Không cần đồng bộ hóa, tôi cho rằng viết tự động viết dễ bay hơi là cần thiết về mặt kỹ thuật (mặc dù IDE đánh dấu nó là không có hiệu lực). Với khối đồng bộ, tôi nghĩ rằng nó vẫn còn cần thiết (kể từ khi đọc là không đồng bộ), nhưng tôi chỉ muốn xác nhận vì nó có vẻ vô lý trong mã nếu nó không thực sự cần thiết. Tôi không chắc chắn nếu có bất kỳ đảm bảo rằng tôi không biết giữa kết thúc của một khối đồng bộ và đọc dễ bay hơi.
Cảm ơn bạn đã trả lời, rõ ràng và xác nhận những gì tôi nghi ngờ. Các lời khuyên liên quan đến việc có hai biến bộ nhớ cache cũng có lẽ là một ý tưởng tốt vì nó tránh có ai đó loại bỏ việc tự gán (mặc dù ý kiến cảnh báo không). –