2009-11-20 32 views

Trả lời

41

Vì, bạn đợi một đối tượng cụ thể (hoặc cụ thể là màn hình của nó) để sử dụng chức năng này.

Tôi nghĩ bạn có thể nhầm lẫn về cách các phương thức này hoạt động. Chúng không đơn giản ở cấp độ chi tiết của Chủ đề, tức là không phải là trường hợp chỉ cần gọi wait() và được đánh thức bởi cuộc gọi tiếp theo tới notify(). Thay vào đó, bạn luôn gọi wait() trên một đối tượng cụ thể và sẽ chỉ bị đánh thức bởi các cuộc gọi đến notifytrên đối tượng đó.

Điều này là tốt bởi vì nếu không các nguyên tắc tương tranh đồng thời sẽ không mở rộng quy mô; nó sẽ tương đương với các không gian tên chung, vì bất kỳ lệnh gọi nào đến notify() ở bất kỳ đâu trong chương trình của bạn sẽ có khả năng gây rối bất kỳ mã nào đồng thời khi chúng đánh thức mọi chuỗi chặn trên cuộc gọi wait(). Do đó lý do mà bạn gọi chúng trên một đối tượng cụ thể; nó cho một bối cảnh cho cặp thông báo chờ đợi hoạt động, vì vậy khi bạn gọi myBlockingObject.notify(), trên một đối tượng riêng tư, bạn có thể chắc chắn rằng bạn sẽ chỉ đánh thức các chủ đề gọi là các phương thức chờ trong lớp của bạn. Một số chủ đề Spring có thể đang chờ trên một đối tượng khác sẽ không bị đánh thức bởi cuộc gọi này và ngược lại.

Chỉnh sửa: Hoặc để giải quyết từ góc độ khác - tôi mong đợi từ câu hỏi của bạn, bạn cho rằng bạn sẽ xử lý chuỗi chờ và gọi notify() trên số để làm chủ đề đó. Lý do nó không được thực hiện theo cách này, là bạn sẽ phải làm rất nhiều vệ sinh cho mình. Các chủ đề sẽ chờ đợi sẽ phải xuất bản một tham chiếu đến chính nó một nơi nào đó mà các chủ đề khác có thể nhìn thấy nó; điều này sẽ phải được đồng bộ hóa chính xác để thực thi tính nhất quán và khả năng hiển thị. Và khi bạn muốn đánh thức một chủ đề, bạn phải giữ nguyên tham chiếu này, đánh thức nó và xóa nó khỏi bất cứ nơi nào bạn đọc nó. Có nhiều giàn giáo thủ công hơn bao gồm, và rất nhiều cơ hội bị lỗi với nó (đặc biệt là trong môi trường đồng thời) so với chỉ gọi myObj.wait() trong chủ đề ngủ và sau đó là myObj.notify() trong sợi chỉ.

+7

Điều này không bắt đầu trả lời tại sao bạn có thể đợi bất kỳ đối tượng nào. Tại sao không có lớp hoặc loại Khóa cụ thể? Hoặc có thể là một giao diện điểm đánh dấu? – mjaggard

+0

"... có khả năng làm hỏng bất kỳ mã đồng thời nào vì chúng sẽ đánh thức mọi chuỗi chặn trên cuộc gọi chờ() ..."Đó là OK miễn là" mess up "có nghĩa là" giới hạn hiệu suất. "Nó không nên thực sự phá vỡ bất cứ điều gì vì một _always_ gọi wait() trong một vòng lặp cho đến khi điều kiện một đang chờ đợi trở thành sự thật. –

8

Bởi vì chỉ có một chủ đề tại một thời điểm có thể sở hữu màn hình của đối tượng và màn hình này là những gì các chủ đề đang chờ hoặc thông báo. Nếu bạn đọc javadoc cho Object.notify()Object.wait(), nó được mô tả chi tiết.

+0

Xin cảm ơn Taylor – Bhupi

+0

Bạn được chào đón. –

10

Lý do đơn giản và rõ ràng nhất là bất kỳ đối tượng nào (không chỉ là một chủ đề) có thể là màn hình cho một chuỗi. Việc chờ và thông báo được gọi trên màn hình . Chuỗi chạy kiểm tra với màn hình. Vì vậy, các phương thức chờ và thông báo nằm trong Object và không phải là Chủ đề

0

Đọc here để được giải thích về việc chờ và thông báo.

Bạn nên tránh những điều này trong ứng dụng của mình và sử dụng gói java.util.concurrent mới hơn.

1

Cơ chế đồng bộ hóa liên quan đến khái niệm - giám sát của một đối tượng. Khi wait() được gọi, màn hình được yêu cầu và thực hiện tiếp tục bị đình chỉ cho đến khi màn hình được mua hoặc InterruptedException xảy ra. Khi thông báo() được gọi, màn hình sẽ được giải phóng.

Hãy lấy một kịch bản nếu wait() và notify() được đặt trong lớp Thread thay vì lớp Object. Tại một thời điểm trong mã, currentThread.wait() được gọi và sau đó một đối tượng anObject được truy cập.

//......... 
currentThread.wait(); 
anObject.setValue(1); 
//......... 

Khi currentThread.wait() được gọi, theo dõi của currentThread được yêu cầu và không thực hiện tiếp tục được thực hiện cho đến khi một trong hai màn hình được mua lại hoặc InterruptedException xảy ra. Bây giờ trong khi chờ trạng thái, nếu một phương thức foo() của một đối tượng khác anotherObject cư trú trong currentThread được gọi từ một chuỗi khác, nó bị kẹt mặc dù phương thức được gọi là foo() không truy cập anObject. Nếu phương thức wait() đầu tiên được gọi là anObject, thay vì chính chuỗi đó, các cuộc gọi phương thức khác (không truy cập anObject) trên các đối tượng cư trú trong cùng một luồng sẽ không bị kẹt. Do đó, các phương thức wait() và notify() gọi trên lớp Object (hoặc các lớp con của nó) cung cấp đồng thời lớn hơn và đó là lý do tại sao các phương thức này nằm trong lớp Object, chứ không phải trong lớp Thread.

0

Tôi sẽ đặt nó trong một cách đơn giản:

Để gọi wait() hoặc thông báo(), bạn cần phải sở hữu màn hình đối tượng - điều này có nghĩa là chờ đợi() hoặc thông báo() cần phải có mặt trong đồng bộ chặn

synchronized(monitorObj){ 
monitorObj.wait() or even notify 
} 

Thats lý do những phương pháp này hiện diện trong lớp đối tượng

0

Điều này là do, những phương pháp này cho liên lạc chủ đề và interthreadcommunication xảy ra bằng cách sử dụng ổ khóa, ổ khóa nhưng có liên quan đến objects.hence nó là trong lớp đối tượng.

0

Phương thức Chờ và Thông báo được sử dụng liên lạc giữa hai Chủ đề trong Java. Vì vậy, lớp Object là nơi chính xác để làm cho chúng có sẵn cho mọi đối tượng trong Java.

Lý do khác là Khóa được tạo sẵn trên mỗi cơ sở Đối tượng. Chủ đề cần khóa và họ chờ khóa, họ không biết chủ đề nào giữ khóa thay vì họ chỉ biết khóa được giữ bởi một số chủ đề và họ phải đợi khóa thay vì biết luồng nào nằm trong khối được đồng bộ và yêu cầu chúng giải phóng khóa

1

Một vài câu trả lời khác sử dụng từ "giám sát", nhưng không có câu trả lời nào giải thích ý nghĩa của từ đó.

Tên "màn hình" được đặt cách ngược lại vào những năm 1970 và nó đề cập đến một đối tượng có khóa nội tại riêng và cơ chế chờ/thông báo liên quan. https://en.wikipedia.org/wiki/Monitor_%28synchronization%29

Hai mươi năm sau, có một thời gian ngắn khi máy tính để bàn, máy tính đa xử lý mới, và thời trang để nghĩ rằng cách thiết kế phần mềm phù hợp là tạo các chương trình hướng đối tượng trong đó mỗi đối tượng là một màn hình.

Biến ra không phải là một ý tưởng hữu ích như vậy, nhưng khoảnh khắc ngắn đó xảy ra chính xác khi ngôn ngữ lập trình Java được phát minh.

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