CodeGym/Blog Java/Ngẫu nhiên/Phương thức Wait() trong Java

Phương thức Wait() trong Java

Xuất bản trong nhóm
Trong bài viết này, chúng ta sẽ xem xét phương thức wait() để kiểm soát luồng và các phương thức notify() / notifyAll() . Các phương thức này được định nghĩa trong lớp cơ sở java.lang.Object và theo đó, các cơ chế kế thừa trong Java cung cấp các phương thức này cho tất cả các lớp. Nghĩa là, khi bạn tạo lớp của riêng mình và các đối tượng của nó, bạn luôn có thể gọi các phương thức này.

Các phương thức wait() và notify()/notifyAll() hoạt động như thế nào?

  • đợi() . tóm lại, phương thức này giải phóng màn hình và đặt luồng đang gọi vào trạng thái chờ cho đến khi một luồng khác gọi phương thức notify() / notifyAll() ;
  • thông báo() . Tiếp tục công việc của một luồng có phương thức wait() đã được gọi trước đó;
  • phương thức notifyAll() tiếp tục lại tất cả các luồng trước đó đã gọi phương thức wait() của chúng .
Bây giờ chúng ta hãy xem xét kỹ hơn về phương thức wait() . Lớp Object chứa ba tùy chọn cho phương thức này:
  • chờ đợi khoảng trống bản địa cuối cùng công khai (thời gian chờ dàiMillis) ném InterruptedException ; Nó làm cho luồng hiện tại đợi cho đến khi nó được đánh thức. Thông thường nó xảy ra khi được thông báo hoặc bị gián đoạn hoặc cho đến khi hết một khoảng thời gian thực nhất định.

  • public final void wait() ném InterruptedException . Không phải ngẫu nhiên mà chúng tôi đã viết một phương thức không có tham số như phương thức thứ hai. Trên thực tế, nếu bạn xem mã của nó, nó đề cập đến biến thể đầu tiên của phương thức, nó chỉ có đối số 0L.

  • chờ đợi cuối cùng công khai​(thời gian chờ lâu, int nanos) . Làm cho luồng hiện tại đợi cho đến khi nó được đánh thức, thường là do được thông báo hoặc bị gián đoạn hoặc cho đến khi hết một lượng thời gian thực nhất định.

Phương thức wait () được dùng để tạm dừng chuỗi cuộc gọi. Nó có nghĩa là gì? Các phương thức này thuộc về lớp. Dựa trên lớp, bạn tạo một đối tượng. Đối tượng tồn tại trong một số chủ đề. Đó là, các đối tượng được tạo trong một số chủ đề. Trong chuỗi mà đối tượng này hoạt động, nếu bạn gọi hàm wait() trong đó, điều này sẽ dẫn đến thực tế là chuỗi này sẽ dừng lại. Bản thân đối tượng hoạt động như một loại màn hình. Nó là gì? Rõ ràng là bạn có thể tạo các đối tượng khác nhau và tất cả chúng sẽ chứa hàm wait()phương pháp. Có một sự hiểu biết về đối tượng nào gây ra điểm dừng của một luồng cụ thể. Chuỗi dừng và sẽ đợi miễn là nó được ghi trong tham số. Và sau đó nó sẽ bắt đầu. Chuỗi này không thể tự bắt đầu. Để tiếp tục công việc, có các phương thức thông báo và thông báo Tất cả. Cuộc gọi đến thông báo () hoặc thông báo Tất cả () phải phát một số luồng khác. Với wait() , bạn có thể dừng nhiều luồng và bắt đầu tất cả các luồng với notifyAll() . Nếu nhiều luồng bị dừng và thông báo() được gọi, thì không thể biết chính xác luồng nào sẽ tiếp tục phương thức này. Nếu không có chuỗi chờ nào trên phương thức wait() , thì không có gì xảy ra khi notify() hoặcnotifyAll() được gọi. Một luồng chỉ có thể gọi các phương thức wait() hoặc notify() trên một đối tượng cụ thể nếu nó hiện có một khóa trên đối tượng đó. wait() , notify()notifyAll() chỉ nên được gọi từ mã được đồng bộ hóa.

Ví dụ về phương thức Wait()

Ở đây chúng ta có một trong những ví dụ phổ biến nhất minh họa cách thức hoạt động của phương pháp này. Giả sử chúng ta có một cửa hàng, nhà sản xuất và người tiêu dùng. Nhà sản xuất chuyển một số sản phẩm sản xuất đến cửa hàng, sau đó người tiêu dùng có thể lấy chúng. Giả sử nhà sản xuất phải sản xuất 8 hàng hóa tương ứng thì người tiêu dùng phải mua tất cả. Nhưng đồng thời, không thể có quá 6 mặt hàng trong kho cùng một lúc. Để giải quyết vấn đề này, chúng ta sử dụng các phương thức wait()notify() . Hãy xác định ba lớp: Thị trường , Nhà sản xuấtKhách hàng . Phương thức Nhà sản xuất trong run() thêm 8 sản phẩm vào đối tượng Thị trường bằng cách sử dụngphương thức put() . Máy khách trong phương thức run() trong một vòng lặp gọi phương thức get của đối tượng Market để lấy các sản phẩm này. Các phương thức đặt và nhận của lớp Thị trường được đồng bộ hóa. Để theo dõi sự hiện diện của hàng hóa trong lớp Market , chúng tôi kiểm tra giá trị của biến mặt hàng. Phương thức get() để lấy sản phẩm chỉ kích hoạt nếu có ít nhất một sản phẩm. Do đó, trong phương thức get, chúng tôi kiểm tra xem sản phẩm có bị thiếu hay không. Nếu mục không có sẵn, phương thức wait() được gọi. Phương thức này giải phóng màn hình của đối tượng Market và chặn phương thức get cho đến khi thông báo ()phương pháp được gọi trên cùng một màn hình. Khi một mục được thêm vào trong phương thức put()thông báo() được gọi, phương thức get() sẽ lấy màn hình. Sau đó, khách hàng của chúng tôi nhận được một mặt hàng. Để thực hiện việc này, một thông báo sẽ hiển thị và giá trị của mục sẽ giảm đi. Cuối cùng, lệnh gọi phương thức notify() báo hiệu phương thức put() tiếp tục. Trong phương thức put() , logic tương tự cũng hoạt động, chỉ hiện tại phương thức put() sẽ hoạt động nếu không có nhiều hơn 6 sản phẩm trong Thị trường .
class Market {

   private int item = 0;

   public synchronized void get() {
       //here we use wait() method
       while (item < 1) {
           try {
               wait();
           }
           catch (InterruptedException e) {
           }
       }
       item--;
       System.out.println("A client has bought 1 item...");
       System.out.println("Items quantity in Market warehouse... " + item);
       notify();
   }

   public synchronized void put() {
       //here we use wait() method when the Warehouse is full
       while (item >= 6) {
           try {
               wait();
           }
           catch (InterruptedException e) {
           }
       }
       item ++;
       System.out.println("Manufacturer has added 1 more item...");
       System.out.println("Now there are " + item + " items in Warehouse" );
       notify();
   }
}

class Manufacturer implements Runnable {

   Market market;

   Manufacturer(Market market) {
       this.market = market;
   }


   public void run() {
       for (int i = 0; i < 8; i++) {
           market.put();
       }
   }
}

class Client implements Runnable {

   Market market;
   Client(Market market) {
       this.market = market;
   }
   public void run() {
       for (int i = 0; i < 8; i++) {
           market.get();
       }
   }
}
//wait() method test class
public class WaitTest {
   public static void main(String[] args) {

       Market market = new Market();
       Manufacturer manufacturer = new Manufacturer(market);
       Client client = new Client(market);
       new Thread(manufacturer).start();
       new Thread(client).start();
   }
}
Ở đây, sử dụng hàm wait() trong phương thức get() , chúng ta đang đợi Nhà sản xuất thêm một mặt hàng mới. Và sau khi thêm, chúng tôi gọi thông báo() , như để nói rằng một địa điểm đã trở nên miễn phí trên Kho và bạn có thể thêm nhiều hơn nữa. Trong phương thức put() , sử dụng wait() , chúng tôi đang chờ giải phóng dung lượng trên Kho . Sau khi không gian trống, chúng tôi thêm mục, thông báo () bắt đầu chuỗi và Khách hàng có thể nhận mục. Đây là đầu ra của chương trình của chúng tôi:
Nhà sản xuất đã thêm 1 mặt hàng nữa... Hiện tại có 1 mặt hàng trong Kho Nhà sản xuất đã thêm 1 mặt hàng nữa... Hiện tại có 2 mặt hàng trong Kho Nhà sản xuất đã thêm 1 mặt hàng nữa... Hiện tại có 3 mặt hàng trong Kho Nhà sản xuất đã thêm 1 mặt hàng nữa... Hiện tại có 4 mặt hàng trong Kho Nhà sản xuất đã thêm 1 mặt hàng nữa... Hiện tại có 5 mặt hàng trong Kho Nhà sản xuất đã thêm 1 mặt hàng nữa... Hiện tại có 6 mặt hàng trong Kho Một khách hàng đã mua 1 sản phẩm... Số lượng mặt hàng trong kho Chợ... 5 Một khách hàng đã mua 1 sản phẩm... Số lượng mặt hàng trong kho Chợ... 4 Một khách hàng đã mua 1 sản phẩm... Số lượng mặt hàng trong kho Chợ... 3 Một khách hàng đã mua 1 sản phẩm... Số lượng mặt hàng trong kho Chợ... 2 Một khách hàng đã mua 1 sản phẩm... Số lượng mặt hàng trong kho Chợ... 1 Một khách hàng đã mua 1 sản phẩm... Số lượng mặt hàng trong kho Chợ... 0 Nhà sản xuất đã thêm 1 mặt hàng nữa... Hiện tại có 1 mặt hàng trong Kho Nhà sản xuất đã thêm 1 mặt hàng nữa... Hiện tại có 2 mặt hàng trong Kho Một khách hàng đã mua 1 sản phẩm... Số lượng mặt hàng trong kho Chợ... 1 Một khách hàng đã mua 1 sản phẩm... Số lượng mặt hàng trong kho Chợ... 0 Quá trình kết thúc với mã thoát 0
Bình luận
  • Phổ biến
  • Mới
Bạn phải đăng nhập để đăng nhận xet
Trang này chưa có bất kỳ bình luận nào