← Back to Advanced Java Course | Chapter 2: Multithreading | Lesson 5 of 8

Java wait और notify

wait और notify threads को एक-दूसरे को signal करने देते हैं, जैसे कोई व्यक्ति किसी दोस्त की 'खाना तैयार है' की आवाज़ का इंतज़ार कर रहा हो। एक thread रुक जाता है जब तक दूसरा न कहे कि वह आगे बढ़ सकता है।
Syntax
java
synchronized (lockObject) {
    while (!condition) {
        lockObject.wait();
    }
    lockObject.notify();  // or notifyAll()
}

Inter-Thread Communication

Inter-thread communication synchronized threads को Object class से inherited तीन methods का उपयोग करके अपना काम coordinate करने और signals exchange करने देता है: wait(), notify(), और notifyAll()। ये threads को loop में बेकार में poll करने के बजाय program में कहीं और conditions बदलने तक रुकने देते हैं।

उदाहरण: Inter-Thread Communication

java
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) throws InterruptedException {
		// Create a new Object object and store it in monitor
		Object monitor = new Object();
		// synchronized lets only one thread run this code at a time
		synchronized (monitor) {
			// Print a line to the console
			System.out.println("wait()/notify()/notifyAll() coordinate threads via this monitor");
		}
	}
}

The wait() Method

किसी synchronized block के अंदर wait() call करना तुरंत calling thread को रोक देता है और, सबसे ज़रूरी बात, उस monitor lock को release कर देता है जो वह रखे हुए था, दूसरे threads को वही lock पाने और आगे बढ़ने देते हुए। waiting thread तब तक रुका रहता है जब तक कोई दूसरा thread उसी object पर notify() या notifyAll() call न करे।

उदाहरण: The wait() Method

java
public class Main {
	public static void main(String[] args) throws InterruptedException {
		final Object lock = new Object();
		Thread waiter = new Thread(() -> {
			synchronized (lock) {
				try {
					System.out.println("Waiting...");
					lock.wait(200); // releases the lock while paused
					System.out.println("Resumed");
				} catch (InterruptedException e) {}
			}
		});
		waiter.start();
		waiter.join();
	}
}

The notify() Method

notify() method object के monitor lock का इंतज़ार कर रहे किसी एक, मनमाने ढंग से चुने गए thread को जगाता है। इसे उसी object पर किसी synchronized block के अंदर से call करना चाहिए, और अगर कई threads इंतज़ार कर रहे हों, तो कोई गारंटी नहीं कि कौन सा चुना जाएगा।

उदाहरण: The notify() Method

java
// Define the class Main
public class Main {
	// Program entry point: the JVM starts running here
	public static void main(String[] args) throws InterruptedException {
		// Create a new Object object and store it in lock
		final Object lock = new Object();
		// Create a new Thread object and store it in waiter
		Thread waiter = new Thread(() -> {
			// synchronized lets only one thread run this code at a time
			synchronized (lock) {
				// Try code that might throw an exception
				try { lock.wait(); } catch (InterruptedException e) {}
				// Print a line to the console
				System.out.println("Woken by notify()");
			}
		});
		// Start the thread; it runs in parallel with this code
		waiter.start();
		Thread.sleep(100);
		synchronized (lock) { lock.notify(); }
		waiter.join();
	}
}

The notifyAll() Method

notifyAll() method सिर्फ एक के बजाय object के monitor का इंतज़ार कर रहे हर thread को जगाता है। जब कई threads अलग-अलग conditions के लिए इंतज़ार कर रहे हों तो यह आमतौर पर notify() से ज़्यादा सुरक्षित विकल्प है, क्योंकि notify() अकेले गलती से गलत वाले को जगा सकता है।

उदाहरण: The notifyAll() Method

java
public class Main {
	public static void main(String[] args) throws InterruptedException {
		final Object lock = new Object();
		Runnable waitTask = () -> {
			synchronized (lock) {
				try { lock.wait(); } catch (InterruptedException e) {}
				System.out.println(Thread.currentThread().getName() + " woken");
			}
		};
		Thread t1 = new Thread(waitTask), t2 = new Thread(waitTask);
		t1.start(); t2.start();
		Thread.sleep(100);
		synchronized (lock) { lock.notifyAll(); } // wakes both, not just one
		t1.join(); t2.join();
	}
}

Producer-Consumer Simulation

Classic producer-consumer pattern किसी shared, bounded buffer को coordinate करने के लिए wait() और notify() का उपयोग करता है: producer तब wait() call करता है जब buffer भरा हो, और consumer तब wait() call करता है जब वह खाली हो, दोनों तरफ buffer की state बदलने के बाद दूसरे को जगाने के लिए notify() call करते हैं।

उदाहरण: Producer-Consumer Simulation

java
// Import java.util.LinkedList so it can be used by its short name
import java.util.LinkedList;
// Define the class Main
public class Main {
	// Create a new LinkedList object and store it in buffer
	static final LinkedList<Integer> buffer = new LinkedList<>();
	static final int CAPACITY = 1;
	// Program entry point: the JVM starts running here
	public static void main(String[] args) throws InterruptedException {
		// Create a new Thread object and store it in producer
		Thread producer = new Thread(() -> {
			// synchronized lets only one thread run this code at a time
			synchronized (buffer) {
				while (buffer.size() == CAPACITY) { try { buffer.wait(); } catch (InterruptedException e) {} }
				buffer.add(42);
				// Print a line to the console
				System.out.println("Produced 42");
				buffer.notify();
			}
		});
		Thread consumer = new Thread(() -> {
			// synchronized lets only one thread run this code at a time
			synchronized (buffer) {
				while (buffer.isEmpty()) { try { buffer.wait(); } catch (InterruptedException e) {} }
				System.out.println("Consumed " + buffer.poll());
			}
		});
		producer.start(); producer.join();
		consumer.start(); consumer.join();
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. उसी object पर किसी synchronized block के बाहर wait() या notify() call करना, जो IllegalMonitorStateException फेंकता है।
  2. wait() से पहले condition को if से जांचना बजाय while loop के, जिससे एक spurious wakeup या कोई दूसरा thread condition को false छोड़ सकता है जब thread जारी रहता है।
  3. दूसरे thread के wait() call करने से पहले notify() call करना, जिससे signal खो जाता है और waiting thread हमेशा के लिए सोता रहता है।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.