2012-06-20 18 views
14

Câu hỏi đơn giản: mô hình bộ nhớ/đồng bộ hóa Java có đảm bảo ghi con trỏ nguyên tử không? Đó là, nếu chúng ta có đề cạnh tranh:Con trỏ Java có viết nguyên tử không?

String shared; 

thread1() 
{ 
    shared = "a"; 
} 

thread2() 
{ 
    shared = "hello world"; 
} 

bắt đầu cùng một lúc, được shared luôn đảm bảo được null, "a", hoặc "hello world"?

+0

Lưu ý, nói chung, đối tượng được tham chiếu bởi tham chiếu có thể không được khởi tạo đầy đủ. Việc thực hiện bình thường của 'String' sẽ không sao, mặc dù đặc điểm kỹ thuật không phải là tuyệt vời trên những thứ này. Ngoài ra còn có một vài loại thực sự quý giá. Nếu bạn cố gắng dựa vào loại điều này, bạn có thể làm điều gì đó sai (mặc dù đó không phải là một lý do chính đáng để không hiểu tại sao). –

Trả lời

3

Nó sẽ là một trong ba giá trị đó, có - nhưng không xác định. Người cuối cùng trong "thắng".

Bạn không yêu cầu, nhưng để hoàn thành - nó sẽ KHÔNG là "hello wor" hoặc một số phiên bản một phần của chuỗi đó.

4

Có. Từ section 17.7 of the JLS:

Ghi và đọc tham chiếu luôn là nguyên tử, bất kể chúng được triển khai dưới dạng giá trị 32 bit hay 64 bit.

(Điều đó không có nghĩa là bạn sẽ luôn nhìn thấy giá trị "mới nhất", nhưng đó là một vấn đề khác.)

+0

Là một hệ quả, tại sao đặc tả của Java yêu cầu con trỏ 64-bit nguyên tử viết nhưng không giống với chữ viết dài? – donnyton

+0

@donnyton, tham chiếu phải là nguyên tử và tôi không biết ngôn ngữ nào mà tham chiếu/con trỏ không phải là nguyên tử (nếu được căn chỉnh đúng). Đối với lý do tại sao longs không được xác định là nguyên tử - mà sẽ bao gồm kiến ​​trúc 32bit và viết nguyên tử có thể tốn kém hơn để đạt được trong khi tài liệu tham khảo trên systen 32bit chỉ ... cũng rộng 32bit. – bestsss

7

Đó là nguyên tử.

Tuy nhiên, trong ví dụ bạn đưa ra, shared 's giá trị không necessarly một của null, a hoặc hello world. Có thể là, nếu không có sự đồng bộ hóa thích hợp, mỗi luồng sẽ không bao giờ thấy giá trị được thiết lập bởi các luồng khác. Vì vậy, thread 1 sẽ thấy athread 2 sẽ thấy hello world cùng một lúc.

Edit: thêm tài liệu tham khảo cho đoạn cuối cùng để biết thêm đọc

Các JLS giải thích thứ tự của hoạt động được thực hiện bởi chủ đề khác nhau, trong Chapter 17 - Threads and Locks. Cụ thể, trong phần 17.4.5 Happens-before Order. Ngoài ra, các văn bản Java Concurrency in Practice được giải thích rõ ràng.

+2

Tôi không nghĩ rằng có một điều như "cùng một lúc" trong bối cảnh này. Với đồng bộ hóa, chúng sẽ không xảy ra cùng một lúc. Không có đồng bộ hóa, không có khái niệm "thời gian" được áp dụng rõ ràng. –

+2

@DavidSchwartz cho vấn đề này, thuật ngữ "thời gian" được sử dụng vì nó được sử dụng bất kỳ nơi nào khác trong thế giới của chúng tôi.Nó có nghĩa là lúc 9:00 sáng hôm nay, 'thread 1' được xử lý' shared' với giá trị 'a' và' thread 2' coi nó là 'hello world'. Tôi không nghĩ nó đơn giản hơn thế. – yair

+0

Việc sử dụng "thời gian" đó không thể áp dụng cho hai điều không tức thời không có khởi động hoặc dừng được xác định rõ và không được đồng bộ hóa. Ví dụ: nếu bạn muốn hỏi liệu hai người có "sẵn sàng làm việc cùng một lúc" hay không, bạn phải có định nghĩa chính xác về thời điểm "chuẩn bị sẵn sàng cho công việc" - cho dù nhấn nút báo lại trên đồng hồ báo thức của bạn một phần của "sẵn sàng cho công việc" hay không. Nếu điều đó không được xác định rõ, khái niệm "sẵn sàng cho công việc cùng một lúc" cũng không được xác định rõ. Trong bối cảnh này "chúng có xảy ra cùng một lúc không?" không có câu trả lời hữu ích. –