2012-03-04 24 views
6

phép nói rằng tôi có một sợi chạy như thế này:Bắt giá trị của một biến chủ đề từ bên ngoài

private boolean working = true; 

@Override public void run() { 
    working = true; 
    // do something 
    working = false; 
    .... 
} 

và trong Chủ đề chính của tôi tôi đang liên tục đưa ra các trạng thái làm việc với

while(threadClassObject.isWorking()) { 
    System.out.println(threadClassObject.isWorking()); 
} 

có hoạt động không? Tôi đã thử ví dụ này và có vẻ như nó hoạt động. Nhưng có cách nào mà điều này có thể sụp đổ? Ví dụ: xảy ra nếu thread đang trong quá trình thay đổi làm việc trong khi tại chính xác cùng một thời gian mainThread cố gắng để đọc nó?

Trả lời

6

Câu trả lời cho câu hỏi của bạn là câu hỏi có thể hoạt động nhưng mã ở trên là mã rủi ro và có thể vi phạm bất kỳ ngày nào. Hãy thử làm workingvolatile như

private volatile boolean working = true; 

What e.g. happens if the thread is in the process of changing working while at the exact same time the mainThread tries to read it?

hoạt động chuyển nhượng là một hoạt động nguyên tử. Vì vậy, nếu bạn có CPU đơn, hai luồng không bao giờ có thể va chạm trong khi truy cập biến. Nếu bạn có nhiều hơn một cpu, hai luồng có thể va chạm trong khi truy cập biến. Đối với cả hai trường hợp, volatile sẽ đảm bảo rằng giá trị hiển thị với các chủ đề khác.

LƯU Ý: volatile là tốt trong tình huống của bạn, nhưng nếu bạn có dữ liệu phức tạp hơn để chia sẻ qua thread try looking into this

Edit:

Thêm nhận xét cũng là một phần của soln. để làm cho nó rõ ràng hơn.

Về cơ bản, bcoz tối ưu hóa ở cấp cpu, các giá trị đã thay đổi chủ đề của tôi có thể không hiển thị với chủ đề khác. Một ví dụ điển hình là cpu cache bcoz tối ưu hóa các giá trị không bao giờ được phản ánh trong ram mà thread khác có thể được đọc. Dễ bay hơi nói rằng giá trị của biến này có thể được thay đổi bên ngoài phạm vi của chuỗi hiện tại, do đó không có tối ưu hóa nào được thực hiện ...

+0

Ok cảm ơn các bạn đã trả lời câu hỏi, bây giờ đã thay đổi nó thành biến động. Chính xác thì điều gì sẽ xảy ra nếu họ va chạm?Nguyên nhân tôi bây giờ đã thực hiện 2 vòng lặp vô tận, một trong các chủ đề mà constanstly thay đổi biến làm việc và một trong chủ đề chính mà liên tục kiểm tra nó và không có gì xảy ra. –

+0

Về cơ bản bcoz tối ưu hóa ở cấp cpu, giá trị thay đổi một sợi của tôi có thể không được hiển thị cho một chủ đề khác. Một ví dụ điển hình là cpu cache bcoz tối ưu hóa các giá trị không bao giờ được phản ánh trong ram mà thread khác có thể được đọc. Dễ bay hơi nói rằng giá trị của biến này có thể được thay đổi bên ngoài phạm vi của chuỗi hiện tại, do đó không có tối ưu hóa nào được thực hiện ... – havexz

1

Bạn sẽ cần phải sử dụng đồng bộ hóa hoặc AtomicBoolean để cho đó là chuỗi an toàn. Những gì bạn có trong mã của bạn sẽ có vẻ hoạt động, nhưng có thể khi bạn kiểm tra boolean, nó sẽ không có giá trị chính xác, vì vậy bạn sẽ thấy kết quả không mong muốn.

0

Không, không cần thiết phải khóa các kiểu nguyên thủy như boolean. Nếu 'làm việc' là một đối tượng, thì bạn cần phải sử dụng đồng bộ khối.

+3

Nếu nó không phải là 'biến động' thì' isValue() 'được gọi trong cuộc gọi chủ đề chính có thể không thấy giá trị thay đổi. –

+3

Không có nguy cơ quan sát một boolean trong trạng thái một phần, nhưng bạn vẫn có thể gặp rắc rối: không đảm bảo rằng luồng chính sẽ _ever_ xem một ghi được tạo trong chuỗi con trừ khi chương trình thiết lập mối quan hệ xảy ra trước đó bằng ghi và đọc qua đồng bộ hóa một số loại. Điều này là độc lập với việc làm việc là một đối tượng hay một nguyên thủy. – jacobm

3

Bạn cũng có thể muốn thực hiện điều gì đó với "runaway" trong khi vòng lặp chính của bạn:

Việc triển khai hiện tại sẽ tiếp tục quay, không để lại nhiều thời gian CPU còn lại cho các chủ đề của bạn thực hiện run() (hoặc bất kỳ ai khác trong hệ thống, cho rằng vấn đề).

+1

Để xây dựng, 'Thread.sleep' và' Thread.yield' là cả hai cách đơn giản để ngăn chặn điều này xảy ra. Một giải pháp mạnh mẽ hơn sẽ là cơ cấu lại chương trình để hướng sự kiện, hoặc một cái gì đó. – Taymon

+0

Cảm ơn, tôi chỉ thực hiện vòng lặp theo cách đó để kiểm tra nó, vì vậy tôi liên tục truy cập vào biến chủ đề. –

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