📜  Java中的wait()方法及示例(1)

📅  最后修改于: 2023-12-03 15:16:30.643000             🧑  作者: Mango

Java中的wait()方法及示例

在Java中,多线程的处理是一个很常见的问题。而在多个线程之间需要进行交互的时候,就需要使用wait()方法和notify()/notifyAll()方法来实现线程的协调和同步。

wait()方法

wait()方法是一个对象中的方法,它的作用是让线程等待。当一个线程执行到该方法时,它会进入到该对象的等待池中,同时释放该对象的锁。线程在等待期间,不会占用CPU资源。只有当其他线程调用该对象的notify()/notifyAll()方法时,等待的线程才会被唤醒,重新进入到该对象的锁池中,等待获取锁。

wait()方法有三个重载的版本,其基本使用方式如下:

public synchronized void wait() throws InterruptedException;
public synchronized void wait(long timeout) throws InterruptedException;
public synchronized void wait(long timeout, int nanos) throws InterruptedException;

其中,第一个版本是无限等待,直到其他线程调用该对象的notify()/notifyAll()方法;第二个版本是等待一定的时间(timeout)后再重新尝试获取锁,如果这段时间内没有其他线程调用该对象的notify()/notifyAll()方法,那么线程就会自动唤醒;第三个版本是等待指定的时间(timeout+nanos)后再尝试获取锁。

示例

下面用一个简单的示例来说明wait()方法的使用:

public class WaitExample{
    public static void main(String[] args){
        final Object lock = new Object();  // 定义一个锁对象
        Runnable runnable1 = new Runnable(){
            @Override
            public void run(){
                synchronized(lock){  // 获取锁
                    try{
                        System.out.println("线程1开始等待...");
                        lock.wait();  // 线程1等待
                    }catch(InterruptedException e){
                        e.printStackTrace();
                    }
                    System.out.println("线程1被唤醒了。");
                }
            }
        };
        Runnable runnable2 = new Runnable(){
            @Override
            public void run(){
                synchronized(lock){  // 获取锁
                    System.out.println("线程2开始唤醒线程1...");
                    lock.notify();  // 唤醒线程1
                }
            }
        };
        new Thread(runnable1).start();  // 启动线程1
        new Thread(runnable2).start();  // 启动线程2
    }
}

上述代码中,通过synchronized关键字来获取同一对象的锁,然后在线程1中调用lock.wait()方法使线程1进入等待状态。而在线程2中,如果不调用lock.notify()方法,线程1将一直处于等待状态。输出结果如下:

线程1开始等待...
线程2开始唤醒线程1...
线程1被唤醒了。

从输出结果可以看出,线程1在调用wait()方法后进入了等待状态,而线程2调用了notify()方法后唤醒了线程1,让其重新进入到锁池中等待获取锁。