2010-07-06 35 views
8

Tôi đã học được rằng việc gọi phương thức wait() của đối tượng sẽ giải phóng màn hình đối tượng, nếu có.java: wait(), thông báo() và khối đồng bộ

Nhưng tôi có một số câu hỏi liên quan đến gọi notify() trên đối tượng này bằng một thread:

  1. (khi nào) sẽ thread chờ đợi thức dậy, nếu khác (một thứ 3) chủ đề sở hữu màn hình đối tượng trong khi đó ?

  2. chủ đề chờ đợi sẽ thức dậy, nếu chuỗi thứ ba có tên là wait() trên đối tượng này?

  3. là nó có thể để xác định xem một thread đang chờ đợi thông báo một đối tượng cụ thể (java 1.4/java 5)

  4. gì đang xảy ra nếu wait() sẽ được gọi trong phương pháp finalize()?

Trả lời

2
  1. notify sẽ đánh thức một chuỗi đang chờ trên màn hình. Trừ khi và cho đến khi màn hình là không được công nhận, không có chủ đề chờ đợi có thể chạy; wait() phải được gọi trong một khối đồng bộ và do đó khóa phải được giữ để tiếp tục chạy khối đó.
  2. Không đảm bảo. Hãy gọi notifyAll để cung cấp tất cả các chủ đề cơ hội để đánh thức.
  3. Dunno. Bạn có thể có chủ đề thiết lập một biến nói rằng nó chờ đợi trước khi nó đi vào giấc ngủ ...
  4. Đây có lẽ là một ý tưởng tồi. Bạn có thể đưa ra một tình huống mà điều này là cần thiết không?
+0

1. "wait() phải được gọi trong khối đồng bộ" là sai. Nhưng nó nên. 2. Có bạn đã đúng. 3. Tôi nghĩ Chris Denett ở ngay đây. Thread.holdsLock() âm thanh tốt. 4. Đó là một câu hỏi lý thuyết để hiểu các khái niệm. – MRalwasser

+1

@MRalwasser: Không đồng ý, phải không. Có một cái nhìn ở đây: http://stackoverflow.com/questions/2779484/why-must-wait-always-be-in-synchronized-block/ – Marcus

2
  1. Đó là lý do tại sao bạn có phương pháp notify()notifyAll(). Trước đây, đánh thức một luồng đang đợi đối tượng, sau đó đánh thức tất cả các luồng. Một chuỗi chờ sẽ không thức dậy nếu wait() được gọi trong một chuỗi khác.

  2. số

  3. Nó chỉ có thể gọi thread.holdsLock(obj) để xem nếu a thread giữ khóa màn hình trên một đối tượng cụ thể.

  4. Không gọi wait() trong phương thức hoàn tất.

+0

Tôi chấp nhận 2.-4. nhưng câu trả lời của bạn cho 1. là sai. Tôi đang nói về khóa màn hình (khối đồng bộ) – MRalwasser

0

2: Không nhất thiết. notify() đánh thức một các chủ đề đang chờ xử lý. Nó có thể là bản gốc hoặc thứ ba.

3: Sử dụng thread.getState() bạn có thể tìm hiểu xem chuỗi có đang chờ đối tượng hay không, nhưng tôi không biết liệu bạn có thể luôn tìm chính xác đối tượng nào.

3

Khi bạn gọi wait() từ một chuỗi, chuỗi đó dừng thực thi và nó được thêm vào waitset của đối tượng. Khi bạn gọi thông báo() từ một luồng khác, một chuỗi ngẫu nhiên từ waitset được đánh thức, nếu bạn gọi notifyAll() tất cả sẽ sẵn sàng để thực thi.

Khi bạn gọi cho thông báo(), chuỗi đã sẵn sàng để chạy nhưng nó không có nghĩa là nó sẽ được thực hiện ngay lập tức nên hãy cẩn thận.

  1. Nó sẽ đánh thức một sợi từ waitset ngẫu nhiên.

  2. Bạn không biết người nào sẽ được đánh thức trước, nó không theo bất kỳ thứ tự nào.

  3. Thread.getState()

  4. Bạn sẽ tạo ra bế tắc.

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