由于线程与线程之间是抢占式执行是, 因此线程之间的执行顺序是无法预测的, 但有时候又希望可以合理的协调线程之间的先后执行顺序, 所以想完成这个协调工作, 主要涉及到三个方法.
wait()方法
wait的作用
使当前执行代码的线程进入等待;
释放当前锁;
当满足一定条件时会被唤醒,重新获取释放的锁;
wait结束等待的条件
其他线程调用该对象的notify方法;
Wait等待时间超时(wait方法提供了一个带有时间参数的方法,可以指定等待时间);
其他线程调用该等待线程的interrupted方法,导致wait抛出InterruptedException 异常.
代码演示
public static void main(String[] args) throws InterruptedException {
object object = new Object();
synchronized (object) {
System.out.println("等待中");
object.wait();
System.out.println("等待结束");
}
}
当代码执行到object.wait之后就会一直等待下去, 线程进入等待, 如果想唤醒线程就需要使用notify()方法,将线程唤醒.
notify()方法
notify方法由于唤醒等待线程
使用方式
1.方法notify()也要在同步方法或同步块中调用,该方法是用来通知那些可能等待该对象的对象锁 的 其它线程,对其发出通知notify,并使它们重新获取该对象的对象锁。
2.如果有多个线程等待,则有线程调度器随机挑选出一个呈 wait 状态的线程。(并没有 "先来后 到")
3.在notify()方法后,当前线程不会马上释放该对象锁,要等到执行notify()方法的线程将程序执行 完,也就是退出同步代码块之后才会释放对象锁。
代码示例:
public class WaitTask implements Runnable{
private Object locker;
public WaitTask(Object locker){
this.locker = locker;
}
@Override
public void run() {
synchronized (locker){
while (true){
try {
System.out.println("wait 开始");
locker.wait();
System.out.println("wait 结束");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
}
class NotifyTask implements Runnable{
private Object locker;
public NotifyTask(Object locker){
this.locker = locker;
}
@Override
public void run() {
synchronized (locker){
System.out.println("notify 开始");
locker.notify();
System.out.println("notify 结束");
}
}
public static void main(String[] args) {
Object locker = new Object();
Thread thread1 = new Thread(new NotifyTask(locker));
Thread thread2 = new Thread(new WaitTask(locker));
thread2.start();
thread1.start();
}
}
notifyAll()方法
notify方法只是唤醒某一个等待线程, 使用notifyAll方法可以一次唤醒所有的等待线程
范例:使用notifyAll()方法唤醒所有等待线程.
public class WaitTask implements Runnable{
private Object locker;
public WaitTask(Object locker){
this.locker = locker;
}
@Override
public void run() {
synchronized (locker){
try {
System.out.println("WaitTask wait 开始");
locker.wait();
System.out.println("WaitTask wait 结束");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
class WaitTask1 implements Runnable{
private Object locker;
public WaitTask1(Object locker){
this.locker = locker;
}
@Override
public void run() {
synchronized (locker){
try {
System.out.println("WaitTask1 wait 开始");
locker.wait();
System.out.println("WaitTask1 wait 结束");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
class NotifyTask implements Runnable{
private Object locker;
public NotifyTask(Object locker){
this.locker = locker;
}
@Override
public void run() {
synchronized (locker){
System.out.println("notify 开始");
locker.notifyAll();
System.out.println("notify 结束");
}
}
public static void main(String[] args) {
Object locker = new Object();
Thread thread1 = new Thread(new NotifyTask(locker));
Thread thread2 = new Thread(new WaitTask(locker));
Thread thread3 = new Thread(new WaitTask1(locker));
thread2.start();
thread3.start();
thread1.start();
}
}
注意: 虽然notifyAll()方法会唤醒所有等待线程,但线程之间还需要竞争锁,并不遵循先来后到.
本次学习讲解到此为止了, 如果感到对你有帮助的话的,给个免费的赞支持一下作者哦