多線程是一種Java函數,它允許並發執行程序的兩個或更多部分,以最大程度地利用CPU。這種程序的每個部分都稱為線程。因此,線程是進程中的輕量級進程。Multi-threaded程序可能經常會遇到多個線程嘗試訪問相同資源並最終產生錯誤結果的情況。
因此,需要通過某種同步方法來確保在給定的時間點隻有一個線程可以訪問資源。Java提供了一種使用同步塊創建線程並同步其任務的方法。 Java中的已同步塊都用sync關鍵字標記。 Java中的同步塊在某些對象上同步。在同一對象上同步的所有同步塊一次隻能在其中一個線程中執行。
稍後我們將討論這些差異,讓我們通過分別討論以下內容來偷看它們之間的相互關係:
- wait()方法
- notifyAll()方法
1. wait()方法
在多線程中,兩個線程可以使用wait()方法相互進行Inter-thread通信。期望更新的線程負責調用wait()方法,然後該線程將立即進入等待狀態。 wait()方法存在於java.lang.Object類中,而不存在於Thread類中,因為線程可以在任何Java對象上調用此方法。要調用wait()方法,該線程應是該對象的所有者,即該線程應具有該對象的鎖,即該線程應在同步區域內。因此,我們隻能從同步區域調用wait()方法,否則我們將得到RuntimeException並聲明IllegalMonitorStateException。如果線程在任何對象上調用wait()方法,它將立即釋放該特定對象的鎖並進入等待狀態。
用法:
public final void wait()
上麵的方法使當前線程無限期地等待,直到為此對象調用notify()或notifyAll()。
public final native void wait( long microsecond)
public final void wait( long microsecond , int nanosecond)
使用以上兩種方法,我們可以指定一個超時時間,之後線程將自動喚醒。我們可以使用notify()或notifyAll()方法在達到超時之前喚醒線程。
Note:Do remember that every wait() method throws InterruptedException which is a checked exception hence whenever we are using the wait() method compulsory we should handle this InterruptedException either by try-catch or by throws keyword otherwise we will get compile-time error.
2. notifyAll()方法
與wait()相似,在inter-thread通信中使用方法notifyAll()。線程負責執行更新,執行一些更新後,它負責調用notifyAll()方法,然後等待的線程將獲得該通知,並使用更新的項目繼續執行。 notifyAll()也存在於java.lang .Object類中。要在任何對象上調用notifyAll()方法,它們應該是該對象的所有者,即線程應位於同步區域內。因此,我們隻能從同步區域調用notifyAll()方法,否則我們將得到RuntimeException並顯示IllegalMonitorStateExceptiom。可以使用notifyAll()方法向特定對象的所有等待線程發出通知,但是即使有多個線程得到通知,但由於鎖需要鎖定的線程同時隻有一個鎖可用,因此執行將一一執行。
用法:
public final native void notifyAll()
實現方式:
在下麵的示例中,我們創建了一個類“ myThread”,通常在程序中以這種方式命名該類,該程序擴展了Thread類,而Thread類本身又擴展了java.lang .Thread類。此類重寫Thread類中可用的run()方法,線程在run()方法內開始其生命周期。在驅動程序類ThreadN中,我們創建一個對象並調用start方法以開始執行線程,並在ThreadN類中調用run()方法,我們同步了t1線程並將其置於等待狀態。在myThread類內部,我們同步run方法,並在計算總和後使用notifyAll()方法向等待的線程發出通知。
例
Java
// Java Program to illustrate difference between
// wait() and notifyAll() method
// Importing java classes
// Input output classes
import java.io.*;
import java.lang.*;
// All utility classes from
// java.util package
import java.util.*;
// Creating a thread in our myThread class
// by extending the Thread class
// Class 1
// Helper class
class myThread extends Thread {
// Declaring sum variable and
// initializing with zero
// as the current final sum
// as it is before iteration
int sum = 0;
// Method in helper class
// Declaring run method
public void run()
{
// Synchronizing this method
synchronized (this)
{
// Calculating the sum
// Display mwssage
System.out.println(
"child thread start calculation");
// Iterating to calculate the sum
for (int i = 0; i <= 100; i++)
// Updating the current sum where
// last updated sum is final sum
sum += i;
// Display mwssage
System.out.println(
"child thread trying to give notification");
// This keyword refers to current object itself
// Notifing the current waiting thread
// using notifyAll() method
this.notifyAll();
}
}
}
// Class 2
// Main class
class ThreadN {
// Main driver method
public static void main(String[] args)
throws InterruptedException
{
// Creating a thread object
// in the main() method of
// our helper class above
myThread t1 = new myThread();
// Starting the above thread created
// using the start() method
t1.start();
// Synchronizing the thread
synchronized (t1)
{
// Display message
System.out.println(
"main thread trying to call wait method");
// Putting the thread in the waiting state
// using the wait() method
t1.wait();
// Display message
System.out.println("main thread get notify");
// Print and display the sum
System.out.println(t1.sum);
}
}
}
main thread trying to call wait method child thread start calculation child thread trying to give notification main thread get notify 5050
Now if the same program is run on terminal/CMD for custom user defined input then the hard coded input is shown below
Conclusion from the above program verifies the key differences between wait() and notifyAll() methods as follows:
- wait()用於將線程置於等待狀態,而notifyAll()方法喚醒特定對象的所有等待線程。
- 如果線程在任何對象上調用wait()方法,則立即釋放該特定對象的鎖,但是,如果線程在任何對象上調用notifyAll()方法,則也會釋放該特定對象的鎖,但不會立即釋放。
- wait()notifyAll()方法不會引發任何InterruptedException,而方法會引發InterruptedException。
相關用法
- Java notify()和notifyAll()的區別用法及代碼示例
- Java wait()和notify()的區別用法及代碼示例
- Java wait和sleep的區別用法及代碼示例
- Java super()和this()的區別用法及代碼示例
- Java throw和throws的區別用法及代碼示例
注:本文由純淨天空篩選整理自mroshanmishra0072大神的英文原創作品 Difference Between wait() and notifyall() in Java。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。