Java多线程中wait、notify、notifyAll使用详解
简介
Java多线程提供了三个关键字:wait
, notify
和notifyAll
,这三个关键字主要用于线程间的协调与通信,可有效避免线程之间产生相互干扰和互斥的问题。本章节主要对这三个关键字的使用进行详细讲解。
wait方法
语法格式
下面是wait方法的语法格式:
public final void wait() throws InterruptedException
public final native void wait(long timeout) throws InterruptedException
public final void wait(long timeout, int nanos) throws InterruptedException
该方法调用会将当前线程置入“等待池”中,并释放当前线程所持有的锁。直到获得了调用该方法的对象的锁定,并将该线程移出“等待池”。
示例说明
下面是一个简单的示例说明:
public static void main(String[] args) {
final Object obj = new Object();
Thread t1 = new Thread(() -> {
synchronized(obj) {
try {
System.out.println(Thread.currentThread().getName() + "开始执行");
obj.wait();
System.out.println(Thread.currentThread().getName() + "重新获得锁");
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
synchronized(obj) {
System.out.println(Thread.currentThread().getName() + "开始执行");
obj.notify();
System.out.println(Thread.currentThread().getName() + "结束执行");
}
});
t1.start();
t2.start();
}
运行结果:
Thread-0开始执行
Thread-1开始执行
Thread-1结束执行
Thread-0重新获得锁
在这个例子中,我们创建了两个线程t1
和t2
,线程t1
先执行并尝试持有锁,然后调用wait()
方法进入等待池中,释放锁资源。线程t2
执行,并持有锁,然后调用notify()
方法唤醒等待池中的线程t1
。线程t1
被唤醒并重新获得锁,输出结果。
notify方法
语法格式
下面是notify方法的语法格式:
public final native void notify()
该方法调用会唤醒在此对象监视器上等待的单个线程。
示例说明
下面是一个简单的示例说明:
public static void main(String[] args) {
final Object obj = new Object();
Thread t1 = new Thread(() -> {
synchronized(obj) {
try {
System.out.println(Thread.currentThread().getName() + "开始执行");
obj.wait();
System.out.println(Thread.currentThread().getName() + "重新获得锁");
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
synchronized(obj) {
System.out.println(Thread.currentThread().getName() + "开始执行");
obj.notify();
System.out.println(Thread.currentThread().getName() + "结束执行");
}
});
t1.start();
t2.start();
}
运行结果:
Thread-0开始执行
Thread-1开始执行
Thread-1结束执行
Thread-0重新获得锁
在这个例子中,我们创建了两个线程t1
和t2
,线程t1
先执行并尝试持有锁,然后调用wait()
方法进入等待池中,释放锁资源。线程t2
执行,并持有锁,然后调用notify()
方法唤醒等待池中的线程t1
。线程t1
被唤醒并重新获得锁,输出结果。
notifyAll方法
语法格式
下面是notifyAll方法的语法格式:
public final native void notifyAll()
该方法调用会唤醒在此对象监视器上等待的所有线程。
示例说明
下面是一个简单的示例说明:
public static void main(String[] args) {
final Object obj = new Object();
Thread t1 = new Thread(() -> {
synchronized(obj) {
try {
System.out.println(Thread.currentThread().getName() + "开始执行");
obj.wait();
System.out.println(Thread.currentThread().getName() + "重新获得锁");
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(() -> {
synchronized(obj) {
System.out.println(Thread.currentThread().getName() + "开始执行");
obj.notifyAll();
System.out.println(Thread.currentThread().getName() + "结束执行");
}
});
t1.start();
t2.start();
}
运行结果:
Thread-0开始执行
Thread-1开始执行
Thread-1结束执行
Thread-0重新获得锁
在这个例子中,我们创建了两个线程t1
和t2
,线程t1
先执行并尝试持有锁,然后调用wait()
方法进入等待池中,释放锁资源。线程t2
执行,并持有锁,然后调用notifyAll()
方法唤醒等待池中的所有线程。线程t1
被唤醒并重新获得锁,输出结果。
注意事项
-
这三个关键字必须在同步语句块中使用,否则会抛出
IllegalMonitorStateException
异常。 -
wait()
方法释放锁资源,线程进入等待池中,可以被其他线程唤醒。 -
notify()
方法唤醒一个等待池中被调用wait()
方法的线程,如果有多个线程等待,则随机唤醒其中之一。 -
notifyAll()
方法唤醒所有等待池中被调用wait()
方法的线程,这些线程将竞争锁资源。
总结
本章节是Java多线程中三个关键字wait
, notify
和notifyAll
的使用详解,这三个关键字的正确使用方式在线程协调与通信等方面有着重要的作用。在实际开发中,需要注意这三个关键字的使用场景及注意事项,以保证程序的正确性和可靠性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程中wait、notify、notifyAll使用详解 - Python技术站