多线程是Java的一个特性,它允许一个程序的两个或多个部分同时执行,以最大限度地利用CPU。这种程序的每个部分被称为线程。线程是一个进程中的轻量级进程。多线程程序经常会出现这样的情况:多个线程试图访问相同的资源,最后产生错误的结果。
因此,需要通过一些同步方法来确保在某个时间点只有一个线程可以访问资源。Java提供了一种创建线程的方法,并通过使用同步块来同步它们的任务。Java中的同步块是用synchronized关键字标记的。Java中的同步块在某些对象上是同步的。在同一个对象上同步的所有同步块,一次只能有一个线程在里面执行。
我们将在后面讨论它们之间的区别,让我们先来看看它们是如何相互关联的,下面将分别讨论它们:
- wait() 方法
- notifyAll()方法
1. wait() 方法
在多线程中,两个线程可以通过使用wait()
方法进行线程间的通信。期待更新的线程负责调用wait()
方法,然后该线程将立即进入等待状态。wait()
方法存在于java.lang.Object类中,而不是Thread类中,因为线程可以在任何java对象上调用这个方法。要调用任何java对象的wait()方法,线程应该是该对象的所有者,也就是说,线程应该拥有该对象的锁,也就是说,线程应该处于同步区域内。因此只能在同步区域内调用wait()
方法,否则会得到IllegalMonitorStateException的RuntimeException
。如果一个线程在任何对象上调用wait()
方法,它会立即释放该对象的锁,并进入等待状态。
语法:
public final void wait()
上述方法导致当前线程无限期地等待,直到notify()
或notifyAll()
对该对象调用。
public final native void wait( long microsecond)
public final void wait(long microsecond , int nanosecond)
使用上述两种方法,可以指定超时,在此之后线程将自动唤醒。可以在达到超时之前使用 notify( )
或 notifyAll( )
方法唤醒线程。
注意:请记住,每个
wait()
方法都会抛出InterruptedException
,这是一个经过检查的异常,因此每当使用wait()方法强制时,应该通过try-catch
或throws
关键字来处理这个InterruptedException
,否则将得到编译时错误。
2. notifyAll()方法
与wait()
方法类似,notifyAll()
方法用于线程间通信。线程负责执行更新,在执行一些更新后,它负责调用 notifyAll()
方法,然后等待线程将收到该通知并继续执行更新的项目。notifyAll()
也存在于 java.lang 中。对象类。要对任何对象调用 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()
方法给等待的线程发出通知。
例子
实现代码:
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 {
int sum = 0;
public void run()
{
// Synchronizing this method
synchronized (this)
{
// Calculating the sum
// Display message
System.out.println(
"child thread start calculation");
// Iterating to calculate the sum
for (int i = 0; i <= 100; i++)
sum += i;
System.out.println("child thread trying to give notification");
this.notifyAll();
}
}
}
// Class 2
// Main class
class ThreadN {
// Main driver method
public static void main(String[] args)throws InterruptedException
{
myThread t1 = new myThread();
t1.start();
// Synchronizing the thread
synchronized (t1)
{
// Display message
System.out.println("main thread trying to call 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
上述程序的结论验证了wait()和notifyAll()方法之间的主要区别,如下所示:
- wait()方法用于使线程处于等待状态,而notifyAll()方法则是唤醒某个特定对象的所有等待线程。
- 如果一个线程在任何对象上调用wait()方法,它会立即释放该特定对象的锁,但如果一个线程在任何对象上调用notifyAll()方法,它也会释放该特定对象的锁,但不是立即。
- wait()方法会抛出一个InterruptedException,而notifyAll()方法不会抛出任何InterruptedException。
下面以表格的形式来看看两者的区别:
— | wait() | notifyall() |
---|---|---|
1 | wait() 方法定义在Object类中。 |
线程类的notifyAll() 方法用于唤醒所有线程。 |
2 | wait() 方法告诉调用线程(当前线程)放弃锁并进入睡眠状态,直到其他线程进入同一个监视器并调用notify() 或notifyAll() |
它给一个特定对象的所有等待线程发出通知。 |
3 | wait() 方法不能被重写 |
它没有任何返回类型。 |
4 | wait() 方法用于线程间的通信 |
它在对象类中作为最终方法实现。 |
5 | wait() 方法与同步锁紧密结合 |
必须在一个同步方法或块中调用 |
java 中 wait()和 notifyall()的区别
欢迎任何形式的转载,但请务必注明出处,尊重他人劳动成果。
转载请注明:文章转载自 有区别网 [http://www.vsdiffer.com]
本文标题:java 中 wait()和 notifyall()的区别
本文链接:https://www.vsdiffer.com/vs/difference-between-wait-and-notifyall-in-java.html
免责声明:以上内容仅代表 个人看法、理解、学习笔记、总结和研究收藏。不保证其正确性,因使用而带来的风险与本站无关!如本网站内容冒犯了您的权益,请联系站长,邮箱: ,我们核实并会尽快处理。