java 对象的wait/notify详解

java 对象的wait,notify方法是Object类定义的final方法,是无法被重新的,这两个方法的定位是多线程中,控制多个线程对共享资源的调用(典型的如生产者消费者模型), 这两种方法必须在当前线程拥有对象锁monitor的情况下使用,否则会抛出异常。

下面假设共享资源为Queue  queue; 分别说明这两中方法的使用方法。

wait 方法:当前线程已经进入了同步锁的线程的情况下,让自己暂时让出同步锁,并让当前线程进入阻塞状态。以便其他正在等待此锁的线程可以得到同步锁并运行,不带参数调用wait( )==wait(0),表示无限等待,必须要其他的线程调用queue.notify()或者queue.notifyAll()方法才能唤醒。如果当前线程调用带参数方法queue.wait(1000),那么当前线程会进入阻塞,并让出同步锁。

notify/notify方法queue.notifyAll()是当前线程通知其它所有因等待工作资源queue而进入阻塞状态的线程,告诉它们:"等待的兄弟们,我马上要用完资源了,等我释放资源后,你们就可以参与queue资源的争夺了,做好抢的整备吧"其他等待该资源的线程会收到这条"广播";queue.notify( )方法会随机的唤醒一个等待wait资源的线程。

wait和nitify通常在并发任务中配合使用的。请看下面的生产者消费者示例

package thread;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Random;

public class ProducerConsumerInJava {
    private static volatile Queue<Integer> queue = new LinkedList<Integer>();

    public static void main(String[] args) {
        Thread produce = new Produce(queue);
        Thread consume = new Consume(queue);
        produce.start();
        consume.start();

    }

}

class Produce extends Thread {
    private Queue<Integer> queue;

    public Produce(Queue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (queue) {
                if (queue.size() == 100) {
                    try {
                        queue.wait();// 运行了此处后,此时此刻不会执行int a=0;只有被其他线程唤醒,才会接着执行int 1=0;
                        int a = 0;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    int random = new Random().nextInt();
                    queue.add(random);
                    System.out.println("生成一个产品:" + random);
                }
                queue.notifyAll();
            }
        }
    }
}

class Consume extends Thread {
    Queue<Integer> queue;

    public Consume(Queue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        while (true) {
            synchronized (queue) {
                if (queue.isEmpty()) {
                    try {
                        queue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else {
                    Integer remove = queue.remove();
                    System.out.println("消费一个产品:" + remove);
                }
                queue.notifyAll();
            }
        }
    }
}


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页