"Chào, Amigo!"
"Chào, Rishi!"
"Tôi sẽ giới thiệu với các bạn các phương thức wait , notify , và notifyAll của lớp Object ."
"Hôm nay chúng ta sẽ chỉ làm quen với chúng, nhưng chúng ta sẽ quay lại sau và dành nhiều thời gian hơn cho việc này."
"Được rồi."
"Những phương pháp này được phát minh như một phần của cơ chế đồng bộ hóa luồng."
"Hãy để tôi nhắc bạn rằng Java có một cơ chế tích hợp để kiểm soát quyền truy cập vào các tài nguyên (đối tượng) được chia sẻ từ các luồng khác nhau. Một luồng có thể tuyên bố rằng một đối tượng đang bận và các luồng khác sẽ phải đợi cho đến khi đối tượng bận được giải phóng. "
"Tôi nhớ. Bạn làm điều đó bằng cách sử dụng từ khóa được đồng bộ hóa ."
"Phải. Thông thường, mã sẽ giống như thế này:"
public void print()
{
Object monitor = getMonitor();
synchronized(monitor)
{
System.out.println("text");
}
}
"Hãy nhớ làm thế nào nó hoạt động?"
"Đúng. Nếu hai luồng đồng thời gọi phương thức print(), một trong số chúng sẽ nhập khối có nhãn đồng bộ hóa và khóa màn hình, điều này khiến luồng thứ hai sẽ đợi cho đến khi màn hình được giải phóng."
"Phải. Khi một luồng đi vào khối được gắn nhãn đồng bộ hóa, đối tượng giám sát được đánh dấu là bận và các luồng khác sẽ buộc phải đợi đối tượng giám sát được giải phóng. Đối tượng giám sát tương tự có thể được sử dụng trong các phần khác nhau của chương trình. "
"Nhân tiện, tại sao bạn lại chọn tên màn hình?"
"Màn hình là cái mà bạn thường gọi là một đối tượng lưu trữ trạng thái bận hoặc rảnh."
"Và đây là lúc các phương pháp chờ đợi và thông báo phát huy tác dụng."
"Trên thực tế, đây thực sự là hai phương pháp duy nhất. Những phương pháp khác chỉ là sự điều chỉnh của những phương pháp này."
"Bây giờ chúng ta hãy tìm hiểu xem phương pháp chờ đợi là gì và tại sao chúng ta cần nó. "
"Đôi khi có những tình huống trong một chương trình mà một luồng đi vào một khối mã được đồng bộ hóa và khóa màn hình, nhưng không thể tiếp tục vì thiếu một số dữ liệu. Ví dụ: một tệp mà nó cần xử lý chưa hoàn tất tải xuống hoặc một cái gì đó như thế."
"Chúng ta có thể đợi tệp được tải xuống. Bạn có thể kiểm tra tệp đó bằng cách sử dụng vòng lặp. Nếu tệp chưa được tải xuống, hãy ngủ trong một giây hoặc lâu hơn và kiểm tra lại cho đến khi tệp được tải xuống."
"Một cái gì đó như thế này:"
while(!file.isDownloaded())
{
Thread.sleep(1000);
}
processFile(file);
"Nhưng trong trường hợp của chúng tôi, kiểu chờ đợi này quá tốn kém. Vì chuỗi của chúng tôi đã khóa màn hình nên các chuỗi khác cũng buộc phải chờ mặc dù họ có thể đã có dữ liệu họ cần."
" Phương thức wait() được phát minh để giải quyết vấn đề này. Phương thức này làm cho luồng giải phóng màn hình và sau đó «treo» luồng.
"Bạn chỉ có thể gọi phương thức chờ của đối tượng màn hình khi màn hình bận, tức là chỉ bên trong một khối được đồng bộ hóa . Khi điều này xảy ra, luồng tạm thời ngừng chạy và màn hình được giải phóng để các luồng khác có thể sử dụng nó."
"Thường có những trường hợp một luồng sẽ nhập một khối được đồng bộ hóa và chờ cuộc gọi, do đó giải phóng màn hình."
"Sau đó, luồng thứ hai sẽ nhập và bị tạm ngưng, rồi luồng thứ ba, v.v."
"Và làm thế nào để một chủ đề được nối lại?"
"Đối với điều đó, có một phương pháp thứ hai: thông báo."
"Bạn chỉ có thể gọi các phương thức thông báo / thông báo của đối tượng màn hình khi màn hình đang bận, tức là chỉ bên trong một khối được đồng bộ hóa . Phương thức notifyAll đánh thức tất cả các luồng đang chờ trên đối tượng màn hình này."
" Phương thức thông báo 'giải phóng' một luồng ngẫu nhiên, nhưng phương thức notifyAll giải phóng tất cả các luồng «đóng băng» của màn hình này."
"Rất thú vị. Cảm ơn, Rishi."
"Cũng có những điều chỉnh của phương thức wait():"
phương thức đợi () | Giải trình |
---|---|
|
Chuỗi «đóng băng», nhưng nó tự động «giải phóng» sau khi đợi số mili giây được truyền cho phương thức dưới dạng đối số. |
|
Chuỗi «đóng băng», nhưng nó tự động «giải phóng» sau khi đợi số nano giây được truyền cho phương thức dưới dạng đối số. |
"Chúng tôi cũng gọi đây là thời gian chờ có thời gian chờ. Phương pháp này hoạt động giống như thời gian chờ thông thường, nhưng nếu thời gian đã chỉ định đã trôi qua và chuỗi chưa được đánh thức, thì nó sẽ tự đánh thức."
GO TO FULL VERSION