Paano gumagana ang wait() at notify()/notifyAll() na mga pamamaraan?
- maghintay () . sa madaling salita, ang pamamaraang ito ay naglalabas ng monitor at naglalagay ng calling thread sa isang wait state hanggang sa isa pang thread ang tumawag sa notify() / notifyAll() method;
- abisuhan() . Ipinagpapatuloy ang gawain ng isang thread na ang wait() method ay dating tinawag;
- Ang pamamaraan ng notifyAll() ay nagpatuloy sa lahat ng mga thread na dati nang tinawag ang kanilang wait() na pamamaraan.
-
public final native void wait(long timeoutMillis) throws InterruptedException ; Nagiging sanhi ito ng kasalukuyang thread na maghintay hanggang sa ito ay magising. Karaniwan itong nangyayari sa pamamagitan ng pag-abiso o pagkaantala, o hanggang sa lumipas ang isang tiyak na halaga ng real time.
-
public final void wait() throws InterruptedException . Ito ay hindi nagkataon na sumulat kami ng isang pamamaraan na walang mga parameter bilang pangalawa. Sa katunayan, kung titingnan mo ang code nito, ito ay tumutukoy sa unang variant ng pamamaraan, mayroon lamang itong argumentong 0L.
-
pampublikong huling paghihintay (mahabang timeout, int nanos) . Nagiging sanhi ng kasalukuyang thread na maghintay hanggang sa ito ay magising, kadalasan sa pamamagitan ng pag-abiso o pagkaantala, o hanggang sa lumipas ang isang tiyak na tagal ng real time.
Halimbawa ng pamamaraang Wait().
Narito mayroon kaming isa sa mga pinakasikat na halimbawa na naglalarawan kung paano gumagana ang pamamaraan. Sabihin nating mayroon tayong tindahan, producer, at consumer. Ang tagagawa ay naglilipat ng ilang mga produkto ng produksyon sa tindahan, pagkatapos ay maaaring kunin ng mamimili ang mga ito. Hayaang gumawa ang tagagawa ng 8 produkto, ayon sa pagkakabanggit, dapat bilhin ng mamimili ang lahat ng ito. Ngunit sa parehong oras, hindi hihigit sa 6 na mga item ang maaaring nasa bodega nang sabay. Upang malutas ang problemang ito, ginagamit namin ang wait() at notify() na mga pamamaraan. Tukuyin natin ang tatlong klase: Market , Manufacturer at Client . Ang Manufacturer in the run() method ay nagdaragdag ng 8 produkto sa Market object gamit ang nitoput() na pamamaraan. Ang client sa run() method sa isang loop ay tumatawag sa get method ng Market object para makuha ang mga produktong ito. Ang mga put and get na pamamaraan ng klase ng Market ay naka-synchronize. Upang subaybayan ang pagkakaroon ng mga kalakal sa klase ng Market , sinusuri namin ang halaga ng variable ng item. Ang get() na paraan para sa pagkuha ng isang produkto ay dapat lamang gumana kung mayroong kahit isang produkto. Samakatuwid, sa paraan ng pagkuha, sinusuri namin kung nawawala ang produkto. Kung hindi available ang item, tatawagin ang wait() method. Inilalabas ng pamamaraang ito ang monitor ng object ng Market at hinaharangan ang get method hanggang sa notify()Ang pamamaraan ay tinatawag sa parehong monitor. Kapag ang isang item ay idinagdag sa put() method at notify() ay tinawag, get() method ang makakakuha ng monitor. Pagkatapos nito, nakatanggap ang aming kliyente ng isang item. Upang gawin ito, ang isang mensahe ay ipinapakita, at ang halaga ng item ay nababawasan. Panghuli, ang notify() method call ay nagse-signal sa put() method na magpatuloy. Sa put() method, gumagana ang katulad na logic, ngayon lang dapat gumana ang put() method kung wala pang 6 na produkto sa Market .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();
}
}
Dito, gamit ang wait() sa get() method, hinihintay namin ang Manufacturer na magdagdag ng bagong item. At pagkatapos magdagdag, tinatawagan namin ang notify() , na parang sinasabi na ang isang lugar ay naging libre sa Warehouse , at maaari kang magdagdag ng higit pa. Sa put() na paraan, gamit ang wait() , naghihintay kami ng paglabas ng espasyo sa Warehouse . Matapos mabakante ang espasyo, idaragdag namin ang item, sisimulan ng notify() ang thread at maaaring kunin ng Kliyente ang item. Narito ang output ng aming programa: