2010-03-28 1 views
8

Theo Java thread state info chờ cuộc gọi() sẽ dẫn đến một chuỗi bị chuyển sang trạng thái BLOCKED. Tuy nhiên đoạn mã này sẽ cho kết quả (sau khi được gọi) trong một Thread trong WAITING State.Chủ đề Java chờ() => bị chặn?

class bThread extends Thread { 
    public synchronized void run() { 
     try { 
      wait(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

Tôi có điều gì sai không? Ai có thể giải thích hành vi này với tôi? Bất kỳ trợ giúp nào sẽ được đánh giá cao!

+0

Lưu ý phụ: Bạn nên liên kết cuộc gọi chờ với điều kiện. – zgulser

Trả lời

15

Chuỗi đang chờ cho đến khi được thông báo. Sau đó, nó trở thành BLOCKED cố gắng để nhập lại khu vực đồng bộ cho đến khi tất cả các chủ đề khác đã để lại.

phần có liên quan từ các liên kết mà bạn đăng tải (khoảng CHỜ):

Ví dụ, một chủ đề đó đã kêu gọi Object.wait() trên một đối tượng đang chờ đợi một thread để gọi Object.notify() hoặc Object.notifyAll() trên đối tượng đó.

và (khoảng BLOCKED):

Một chủ đề trong tình trạng bị chặn đang chờ đợi một khóa màn hình để [...] nhập lại một khối/phương pháp đồng bộ sau khi gọi Object.wait.

Phần cuối cùng xảy ra khi chuỗi cố gắng trả về từ wait(), nhưng không phải cho đến lúc đó.

+0

có nghĩa là một chuỗi bị chặn nằm trong vòng lặp để lấy khóa không? aka một thread trong trạng thái bị chặn chi phí thời gian CPU? – user2807219

+0

@ user2807219: Không, thường thì không. Chuỗi sẽ nằm trong hàng đợi sẵn sàng của một mutex bảo vệ vùng được đồng bộ hóa, giống như khi bạn đang gọi một hàm đồng bộ bị khóa bởi một luồng khác. Chi phí chính để lo lắng về việc tranh chấp khóa thường là nó buộc các chuyển mạch ngữ cảnh trên chương trình (tức là lưu trữ và khôi phục trạng thái của chuỗi đang chạy trong CPU), điều này tương đối tốn kém. –

1

Đợi là khi nó không làm gì cả. Bị chặn là khi nó cố gắng bắt đầu chạy lại nhưng chưa được phép.

3

Bạn thấy nó nói những thứ như thế ở đâu?

Trong cùng một trang bạn liên kết, thread.state, nó rõ ràng rằng

CHỜ sẽ được sau khi Object.wait()

BLOCKED sẽ trước khi vào đồng bộ

+0

Ồ, tôi thấy điều gì có thể làm bạn bối rối. "BLOCKED => hoặc nhập lại một khối/phương thức đã đồng bộ sau khi gọi Object.wait." .. chú ý đến "reenter a synchronized block" –

9

Màn hình thực thi một thread tại một thời gian. Giả sử bạn có chủ đề T1-T10, 9 là BLOCKED và một là RUNNABLE. Thỉnh thoảng, màn hình chọn một chuỗi mới để chạy. Khi điều đó xảy ra, luồng được chọn/hiện tại, nói T1, đi từ RUNNABLE đến BLOCKED. Sau đó, một chuỗi khác, nói, T2, đi từ BLOCKED đến RUNNABLE, trở thành chuỗi hiện tại.

Khi một trong các chủ đề cần một số thông tin được tạo sẵn bởi một chuỗi khác, bạn sử dụng wait(). Trong trường hợp đó, chuỗi sẽ được gắn cờ là WAITING cho đến khi nó là notify() ed. Vì vậy, một sợi đang chờ sẽ không được thực hiện bởi màn hình cho đến lúc đó. Một ví dụ sẽ là, chờ cho đến khi có các hộp được dỡ xuống. Các chàng trai tải hộp sẽ thông báo cho tôi khi điều đó xảy ra.

Nói cách khác, cả hai BLOCKEDWAITING là trạng thái của chủ đề hoạt động, nhưng một sợi WAITING không thể RUNNABLE mà không đi đến BLOCKED đầu tiên. WAITING chủ đề "không muốn" để trở thành hoạt động, trong khi BLOCKED chủ đề "muốn", nhưng không thể, bởi vì nó không phải là lượt của họ.

Tôi nghĩ vậy.

0

Cũng giống như lời nhắc, bạn nên luôn gọi wait() trong vòng lặp while đang chờ điều kiện để nhập phần được đồng bộ hóa/phần quan trọng. Điều này là bởi vì Java có "wakeback giả" (về cơ bản, một thread có thể đánh thức bất cứ lúc nào không có lý do).

1

Có một số thuật ngữ khó hiểu đang diễn ra tại đây. Khi một cuộc gọi chờ một đối tượng, nó đi vào trạng thái WAIT. Khi chuỗi là chờ để lấy khóa, chúng thuộc về số chờ được đặt cho khóa đó, nhưng chúng ở trạng thái BLOCKED.

Khó hiểu nhưng bằng cách nào đó nó có ý nghĩa!