详解Java的wait()方法:让线程等待

  • Post category:Java

Java中的wait()方法是Object类的一个方法,可以使调用该方法的对象进入等待状态,一直等到其他线程调用该对象的notify()或notifyAll()方法才会被唤醒。下面来详细讲解Java的wait()方法的完整攻略。

wait()方法的语法

wait()方法的语法如下:

public final void wait() throws InterruptedException

wait()方法不需要参数,如果对象没有被锁定,调用该方法会抛出IllegalMonitorStateException异常。该方法被调用之后,当前线程会在该对象上进行等待,并释放锁,直到其他线程调用该对象的notify()或notifyAll()方法。

调用wait()方法的注意事项

调用wait()方法需要注意以下几点:

  1. wait()方法只能在synchronized块内部使用。

  2. wait()方法的调用会让当前线程进入等待状态,并且释放当前线程所持有的锁。

  3. 在调用wait()方法前,需要先获取该对象的锁。

  4. 调用wait()方法后,当前线程会一直等待,直到其他线程调用了该对象的notify()或notifyAll()方法。

  5. 在调用wait()方法时,一定要检查等待的条件,不满足条件时应该调用wait()方法。

wait()方法示例1 – 线程通信

class Data {
    public synchronized void print() {
        try {
            while (!flag) {
                wait();
            }
            System.out.println(Thread.currentThread().getName() + " print data..");
            flag = false;
            notifyAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized void save() {
        try {
            while (flag) {
                wait();
            }
            System.out.println(Thread.currentThread().getName() + " save data..");
            flag = true;
            notifyAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private boolean flag = false;
}

public class ThreadCommunicationDemo {
    public static void main(String[] args) {
        Data data = new Data();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                data.save();
            }
        }, "SaveThread").start();

        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                data.print();
            }
        }, "PrintThread").start();
    }
}

在上面的代码中,Data类有print()和save()方法,分别是打印数据和保存数据。print()方法需要等待数据被保存后才能执行,save()方法需要等待数据被打印后才能执行,两个方法使用了wait()、notify()和notifyAll()方法,在多线程环境下实现了线程之间的通信。

wait()方法示例2 – 队列

public class Queue<E> {
    private LinkedList<E> list = new LinkedList<E>();

    private int maxSize;

    public Queue(int maxSize) {
        this.maxSize = maxSize;
    }

    public synchronized void put(E e) {
        while (list.size() == maxSize) {
            try {
                wait();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        list.addLast(e);
        notifyAll();
    }

    public synchronized E take() {
        while (list.size() == 0) {
            try {
                wait();
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        E e = list.removeFirst();
        notifyAll();
        return e;
    }
}

在上面的代码中,Queue类是一个队列,put()方法用于向队列中添加元素,take()方法用于从队列中取出元素。当队列为空时,执行take()方法会被wait()方法阻塞,直到有新的元素被添加到队列中才会继续执行。当队列已满时,执行put()方法会被wait()方法阻塞,直到有元素被取出队列才会继续执行。

以上就是Java的wait()方法的完整攻略,包含了该方法的语法、注意事项以及两个示例。