2012-02-14 14 views
5

Điều này thực sự lạ đối với tôi, nhưng trông giống như notifyAll()/notify() không thành công trong chương trình của tôi. Mã khá phức tạp, về cơ bản tôi có ba luồng A, B, CJava - notifyAll() và thông báo() không thành công? Có thể không?

Gửi yêu cầu đến B và chờ() theo yêu cầu với thời gian chờ là 10 giây, khi B kết thúc, nó gọi thông báo() để đánh thức lên A.

C trong vòng lặp cung cấp nhiều chuỗi đến A qua hàng đợi, A chọn chúng và in ra. Mỗi lần A in ra một chuỗi nó sẽ gửi một yêu cầu đến B và chờ đợi.

Vì vậy, các công việc nói đến là:

C giữ cho ăn một trong deadloop

  1. Một in ra chuỗi từ C
  2. A gửi yêu cầu đến B và chờ đợi (10)
  3. B thông báo() A ......

  4. Một chuỗi in ra từ C .... lặp đi lặp lại ....

Điều này hoạt động trong vài giây đầu tiên. Tuy nhiên, sau một thời gian tôi thấy khi B in ra rằng nó đã thông báo() A, A vẫn đang đợi vì hàng đợi mà C sử dụng để nạp A đang tăng lên nhanh chóng và không có chuỗi nào được in bởi A. Cuối cùng, sau 10 giây , A khiếu nại thời gian chờ yêu cầu.

Điều này có vẻ như thông báo() không thành công vì B in ra thông báo sau khi nó được gọi là notify(). Do chờ đợi/thông báo là tính năng cấp tiến của java, tôi không thể tin rằng nó sẽ thất bại. Có thể không?

+8

Bạn * chắc chắn * A "vẫn đang chờ"? Khả năng khác là nó * bắt đầu * chờ * sau * thông báo, mã sẽ bị hỏng. (Bạn không bao giờ nên chờ đợi điều gì đó đã xảy ra.) –

+0

Có thể B đã gọi thông báo TRƯỚC KHI Cuộc gọi chờ –

+1

chúng tôi muốn mã xin vui lòng. – vulkanino

Trả lời

2

thông báo() sẽ chỉ hoạt động nếu có một chuỗi chờ() ing cho nó tại thời điểm đó.

Thành ngữ bạn nên sử dụng là thay đổi trạng thái trong cùng một khối được đồng bộ hóa thành thông báo()/notifyAll(). Trong khối chờ đợi, bạn liên tục kiểm tra sự thay đổi trạng thái. Bằng cách đó, nếu thông báo được kích hoạt quá sớm, có một thay đổi trạng thái để ghi lại nó. Ngoài ra nếu chờ đợi wakes giả mạo nó sẽ chờ đợi một lần nữa nếu nhà nước đã không thay đổi.

public synchronized void notifyReady() { 
    ready = true; 
    notifyAll(); 
} 

public synchronized void waitForReady() throws InterruptedException { 
    while(!ready) 
     wait(); 
} 
+0

Cảm ơn các bạn. Vấn đề thời gian đã được chứng minh là nguyên nhân –

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