Tôi đã nhìn thấy loại mã này rất nhiều trong các dự án, trong đó ứng dụng muốn có một trình giữ dữ liệu toàn cầu, vì vậy chúng sử dụng một singleton tĩnh mà bất kỳ luồng nào cũng có thể truy cập.Khả năng hiển thị bộ nhớ của các biến được truy cập trong các trình đơn tĩnh trong Java là gì?
public class GlobalData {
// Data-related code. This could be anything; I've used a simple String.
//
private String someData;
public String getData() { return someData; }
public void setData(String data) { someData = data; }
// Singleton code
//
private static GlobalData INSTANCE;
private GlobalData() {}
public synchronized GlobalData getInstance() {
if (INSTANCE == null) INSTANCE = new GlobalData();
return INSTANCE;
}
}
Tôi hy vọng thật dễ dàng để xem điều gì đang xảy ra. Người ta có thể gọi GlobalData.getInstance().getData()
bất cứ lúc nào trên bất kỳ chủ đề nào. Nếu hai chủ đề gọi setData() với các giá trị khác nhau, ngay cả khi bạn không thể đảm bảo cái nào "thắng", tôi không lo lắng về điều đó.
Nhưng an toàn chỉ là mối quan tâm của tôi ở đây. Điều tôi lo lắng là khả năng hiển thị bộ nhớ. Bất cứ khi nào có một rào cản bộ nhớ trong Java, bộ nhớ đệm được đồng bộ giữa các chủ đề tương ứng. Một rào cản bộ nhớ xảy ra khi đi qua đồng bộ, truy cập vào các biến dễ bay hơi vv
Hãy tưởng tượng kịch bản sau đây xảy ra trong thứ tự thời gian:
// Thread 1
GlobalData d = GlobalData.getInstance();
d.setData("one");
// Thread 2
GlobalData d = GlobalData.getInstance();
d.setData("two");
// Thread 1
String value = d.getData();
Không phải là nó có thể là giá trị cuối cùng của value
trong chủ đề 1 thể vẫn là "one"
? Lý do là, thread 2 không bao giờ được gọi là bất kỳ phương pháp đồng bộ sau khi gọi d.setData("two")
do đó, không bao giờ có một rào cản bộ nhớ? Lưu ý rằng rào cản bộ nhớ trong trường hợp này xảy ra mỗi khi getInstance()
được gọi vì nó được đồng bộ hóa.
Bạn nói 'Người ta có thể gọi GlobalData.getInstance(). GetData() bất kỳ lúc nào trên bất kỳ chuỗi nào. Đó là thread-an toàn vì vậy tôi không lo lắng về điều đó' nhưng nó thực sự không an toàn thread chính xác vì kịch bản mà bạn mô tả. An toàn chủ đề không chỉ là nhìn thấy một vật thể trong trạng thái không nhất quán. Nó cũng về việc xem dữ liệu cũ. – yair
@yair Có nhưng tôi đã thực sự cố gắng để kiểm tra các khía cạnh bộ nhớ khả năng hiển thị như trái ngược với trạng thái không nhất quán dựa trên thực hiện đồng bộ. –