Java >> Java tutoriál >  >> Java

Rozdíl mezi notify a notifyAll v Javě

notify() a notifyAll() spolu s wait() se používají k navázání komunikace mezi vlákny. Vlákno přejde do režimu WAITING voláním wait() metoda. Toto vlákno bude ve stavu WAITING, dokud jakékoli jiné vlákno nezavolá buď notify() nebo notifyAll() metoda na stejném objektu. Podívejte se, jak mezi sebou vlákna komunikují pomocí wait() , notify() a notifyAll() v Javě. Libovolné vlákno volající wait() , notify() a notifyAll() musí mít zámek tohoto objektu. Jinými slovy, tyto metody musí být volány v rámci synchronizované metody nebo synchronizovaného bloku. V tomto příspěvku uvidíme rozdíly mezi notify a notifyAll v Javě s příkladem.

notify() v jazyce Java:

Když vlákno volá notify() metodou na konkrétním objektu bude upozorněno pouze jedno vlákno, které čeká na zámek nebo monitor tohoto objektu. Vlákno vybrané pro oznámení je náhodné, tj. náhodně bude pro oznámení vybráno jedno vlákno. Notifikované vlákno nezíská zámek objektu okamžitě. Dostane se, jakmile volací vlákno uvolní zámek daného objektu. Do té doby bude ve stavu BLOCKED. Jakmile se uzamkne, přejde ze stavu BLOCKED do stavu RUNNING.

Poznámka :Před upozorněním bude vlákno ve stavu WAITING. Jakmile je upozorněn, přejde do stavu BLOCKED. Zůstává ve stavu BLOCKED, dokud se nezamkne. Jakmile získá zámek, přejde ze stavu BLOCKED do stavu RUNNING.

Podívejme se na notify() metoda s příkladem.

class Shared
{
	synchronized void waitMethod()
	{
		Thread t = Thread.currentThread();
		
		System.out.println(t.getName()+" is releasing the lock and going to wait");
		
		try 
		{
			wait();
		}
		catch (InterruptedException e) 
		{
			e.printStackTrace();
		}
		
		System.out.println(t.getName()+" has been notified and acquired the lock back");
	}
	
	synchronized void notifyOneThread()
	{
		Thread t = Thread.currentThread();
		
		notify();
		
		System.out.println(t.getName()+" has notified one thread waiting for this object lock");
	}
}

public class MainClass 
{   
	public static void main(String[] args) 
	{
		final Shared s = new Shared();
		
		//Thread t1 will be waiting for lock of object 's'
		
		Thread t1 = new Thread() 
		{
			@Override
			public void run()
			{
				s.waitMethod();
			}
		};
		
		t1.start();
		
		//Thread t2 will be waiting for lock of object 's'
		
		Thread t2 = new Thread() 
		{
			@Override
			public void run()
			{
				s.waitMethod();
			}
		};

		t2.start();
		
		//Thread t3 will be waiting for lock of object 's'
		
		Thread t3 = new Thread() 
		{
			@Override
			public void run()
			{
				s.waitMethod();
			}
		};
		
		t3.start();
		
		try 
		{
			Thread.sleep(1000);
		} 
		catch (InterruptedException e) 
		{
			e.printStackTrace();
		}
		
		//Thread t4 will notify only one thread which is waiting for lock of object 's'
		
		Thread t4 = new Thread() 
		{
			@Override
			public void run()
			{
				s.notifyOneThread();
			}
		};
		
		t4.start(); 
	}	
}

Výstup:

Vlákno-1 uvolňuje zámek a bude čekat
Vlákno-0 uvolní zámek a bude čekat
Vlákno-2 uvolní zámek a bude čekat
Vlákno-3 oznámilo jedno vlákno čekající na tento zámek objektu
Vlákno-1 bylo upozorněno a získalo zámek zpět

notifyAll() v jazyce Java:

Když vlákno volá notifyAll() metodou na konkrétním objektu jsou upozorněna všechna vlákna, která čekají na uzamčení tohoto objektu. Všechna oznámená vlákna se přesunou ze stavu WAITING do stavu BLOCKED. Všechna tato vlákna získají zámek objektu na základě priority. Vlákno, které objekt uzamkne, se přesune do stavu RUNNING. Zbývající vlákna zůstanou ve stavu BLOCKED, dokud nezískají zámek objektu.

Níže je uveden příklad notifyAll() metoda v Javě.

class Shared
{
	synchronized void waitMethod()
	{
		Thread t = Thread.currentThread();
		
		System.out.println(t.getName()+" is releasing the lock and going to wait");
		
		try 
		{
			wait();
		}
		catch (InterruptedException e) 
		{
			e.printStackTrace();
		}
		
		System.out.println(t.getName()+" has been notified and acquired the lock back");
	}
	
	synchronized void notifyAllThread()
	{
		Thread t = Thread.currentThread();
		
		notifyAll();
		
		System.out.println(t.getName()+" has notified all threads waiting for this object lock");
	}
}

public class MainClass 
{   
	public static void main(String[] args) 
	{
		final Shared s = new Shared();
		
		//Thread t1 will be waiting for lock of object 's'
		
		Thread t1 = new Thread() 
		{
			@Override
			public void run()
			{
				s.waitMethod();
			}
		};
		
		t1.start();
		
		//Thread t2 will be waiting for lock of object 's'
		
		Thread t2 = new Thread() 
		{
			@Override
			public void run()
			{
				s.waitMethod();
			}
		};

		t2.start();
		
		//Thread t3 will be waiting for lock of object 's'
		
		Thread t3 = new Thread() 
		{
			@Override
			public void run()
			{
				s.waitMethod();
			}
		};
		
		t3.start();
		
		try 
		{
			Thread.sleep(1000);
		} 
		catch (InterruptedException e) 
		{
			e.printStackTrace();
		}
		
		//Thread t4 will notify all threads which are waiting for lock of object 's'
		
		Thread t4 = new Thread() 
		{
			@Override
			public void run()
			{
				s.notifyAllThread();
			}
		};
		
		t4.start(); 
	}	
}

Výstup:

Vlákno-0 uvolňuje zámek a bude čekat
Vlákno-2 uvolní zámek a bude čekat
Vlákno-1 uvolní zámek a bude čekat
Vlákno-3 oznámilo všechna vlákna čekající na tento zámek objektu
Vlákno-1 bylo upozorněno a získalo zámek zpět
Vlákno-2 bylo upozorněno a získalo zpět zámek
Vlákno-0 bylo upozorněno a získalo uzamknout zpět

Rozdíl mezi notify a notifyAll v Javě:

Níže uvedený diagram shrnuje rozdíl mezi notify a notifyAll v jazyce Java.


Java Tag