ในบทความนี้ เราจะดูเมธอด wait ( )เพื่อควบคุมเธรด และเมธอด alert() / alertAll() เมธอดเหล่านี้กำหนดไว้ในคลาสพื้นฐานjava.lang.Objectดังนั้นกลไกการสืบทอดที่อยู่ใน Java จึงจัดเตรียมเมธอดเหล่านี้ให้กับทุกคลาส นั่นคือ เมื่อคุณสร้างคลาสและออบเจกต์ของคุณเอง คุณสามารถเรียกใช้เมธอดเหล่านี้ได้ตลอดเวลา
วิธี wait() และ alert()/notifyAll() ทำงานอย่างไร
- รอ () . ในระยะสั้น วิธีการนี้จะปล่อยมอนิเตอร์และทำให้เธรดการโทรอยู่ในสถานะรอจนกว่าเธรดอื่นจะเรียกเมธอดalert () / alertAll()
- แจ้ง () . สานต่อการทำงานของเธรดที่มีการเรียกเมธอด wait() ก่อนหน้านี้
- เมธอด alertAll()ดำเนินการต่อเธรดทั้งหมดที่เคยเรียกเมธอดwait() ไว้ก่อนหน้านี้
-
โมฆะพื้นเมืองสุดท้ายสาธารณะรอ (timeoutMillis นาน)พ่นInterruptedException ; มันทำให้เธรดปัจจุบันรอจนกว่าจะตื่นขึ้น โดยปกติจะเกิดขึ้นโดยได้รับแจ้งหรือขัดจังหวะ หรือจนกว่าจะผ่านเวลาจริงไประยะหนึ่ง
-
โมฆะสาธารณะสุดท้าย wait( ) พ่นInterruptedException ไม่ใช่เรื่องบังเอิญที่เราเขียนเมธอดที่สองโดยไม่มีพารามิเตอร์ อันที่จริง ถ้าคุณดูที่โค้ด มันอ้างถึงตัวแปรแรกของเมธอด มันมีแค่อาร์กิวเมนต์ 0L
-
การรอครั้งสุดท้ายสาธารณะ (ระยะหมดเวลานาน, int nanos ) ทำให้เธรดปัจจุบันรอจนกว่าเธรดจะถูกปลุก โดยทั่วไปโดยการแจ้งเตือนหรือขัดจังหวะ หรือจนกระทั่งเวลาจริงผ่านไประยะหนึ่ง
ตัวอย่างเมธอด Wait()
เรามีหนึ่งในตัวอย่างยอดนิยมที่แสดงให้เห็นว่าวิธีการทำงานเป็นอย่างไร สมมติว่าเรามีร้านค้า ผู้ผลิต และผู้บริโภค ผู้ผลิตโอนผลิตภัณฑ์การผลิตบางส่วนไปยังร้านค้าหลังจากนั้นผู้บริโภคสามารถนำไปได้ ให้ผู้ผลิตต้องผลิตสินค้า 8 อย่าง ตามลำดับ ผู้บริโภคต้องซื้อทั้งหมด แต่ในขณะเดียวกันสามารถมีสินค้าในคลังสินค้าได้ไม่เกิน 6 รายการในเวลาเดียวกัน เพื่อแก้ปัญหานี้ เราใช้เมธอดwait()และalert() มากำหนดคลาสสามคลาส: Market ผู้ผลิตและClient ผู้ผลิตในการเรียกใช้ ()วิธีการเพิ่ม 8 ผลิตภัณฑ์ไปยัง วัตถุ Marketโดยใช้ใส่ ()วิธีการ ลูกค้าในเมธอดrun()ในลูปเรียกเมธอด get ของMarket object เพื่อรับผลิตภัณฑ์เหล่านี้ เมธอด put และ get ของคลาสMarketจะถูกซิงโครไนซ์ ในการติดตามการมีอยู่ของสินค้าใน คลาส Marketเราจะตรวจสอบค่าของตัวแปรรายการ เมธอดget()ในการรับผลิตภัณฑ์ควรเริ่มทำงานเมื่อมีผลิตภัณฑ์อย่างน้อยหนึ่งรายการเท่านั้น ดังนั้นในเมธอด get เราจะตรวจสอบว่าสินค้าหายไปหรือไม่ ถ้ารายการไม่พร้อมใช้งานจะเรียกเมธอดwait() วิธีการนี้เผยแพร่ จอภาพของวัตถุ Marketและบล็อกวิธีการรับจนกว่าจะมีการแจ้งเตือน ()วิธีการถูกเรียกใช้บนจอภาพเดียวกัน เมื่อมีการเพิ่มรายการใน เมธอด put()และalert () เมธอด get()จะได้รับมอนิเตอร์ หลังจากนั้นลูกค้าของเราจะได้รับสินค้า ในการทำเช่นนี้ ข้อความจะปรากฏขึ้น และค่าของรายการจะลดลง ในที่สุด การเรียก เมธอด alert()จะส่งสัญญาณเมธอดput()เพื่อดำเนินการต่อ ใน เมธอด put() ลอจิกที่คล้ายกันใช้ งาน ได้ แต่ตอนนี้เมธอดput()ควรใช้งานได้หากมีผลิตภัณฑ์ไม่เกิน 6 รายการในMarketclass 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();
}
}
ที่นี่ ใช้wait()ใน เมธอด get()เรากำลังรอให้ผู้ผลิตเพิ่มรายการใหม่ และหลังจากเพิ่มแล้ว เราจะโทรไปที่ alert()ราวกับจะบอกว่ามีที่ว่างในคลังสินค้าและคุณสามารถเพิ่มได้อีก ใน เมธอด put()โดยใช้wait ()เรากำลังรอการปล่อยพื้นที่บนคลังสินค้า หลังจากพื้นที่ว่าง เราจะเพิ่มรายการแจ้งเตือน()เริ่มเธรด และไคลเอนต์สามารถรับรายการ นี่คือผลลัพธ์ของโปรแกรมของเรา:
ผู้ผลิตได้เพิ่มอีก 1 รายการ... ตอนนี้มี 1 รายการในคลังสินค้า ผู้ผลิตได้เพิ่มอีก 1 รายการ... ตอนนี้มี 2 รายการในคลังสินค้า ผู้ผลิตได้เพิ่มอีก 1 รายการ... ขณะนี้มี 3 รายการในคลังสินค้าผู้ผลิตมี เพิ่มอีก 1 รายการ... ตอนนี้มี 4 รายการในคลังสินค้า ผู้ผลิตได้เพิ่มอีก 1 รายการ... ขณะนี้มี 5 รายการในคลังสินค้าผู้ผลิต ได้เพิ่มอีก 1 รายการ... ขณะนี้มี 6 รายการในคลังสินค้า ลูกค้าได้ซื้อ 1 รายการ... จำนวนรายการในคลังสินค้า Market... 5 ลูกค้าซื้อสินค้า 1 รายการ... จำนวนรายการในคลังสินค้า Market... 4 ลูกค้าซื้อสินค้า 1 รายการ... จำนวนรายการในคลังสินค้า Market... 3 ลูกค้าซื้อสินค้า 1 รายการ... ปริมาณสินค้าในคลังสินค้า Market... 2 ลูกค้าซื้อสินค้า 1 รายการ... ปริมาณสินค้าในคลังสินค้า Market... 1 ลูกค้าซื้อสินค้า 1 รายการ... ปริมาณสินค้าในคลังสินค้า Market ...0 ผู้ผลิตได้เพิ่มอีก 1 รายการ... ขณะนี้มี 1 รายการในคลังสินค้า ผู้ผลิตได้เพิ่มอีก 1 รายการ... ขณะนี้มี 2 รายการในคลังสินค้า ลูกค้าได้ซื้อ 1 รายการ... ปริมาณรายการในคลังสินค้าตลาด... 1 ลูกค้าซื้อสินค้า 1 รายการ... จำนวนรายการในคลังสินค้าของตลาด... 0 ดำเนินการเสร็จสิ้นด้วยรหัสออก 0