等待(wait)和通知(notify)

来源:互联网 发布:如何在阿里云备案域名 编辑:程序博客网 时间:2024/06/04 19:24

为了支持多线程之间的协作,jdk提供了两个非常重要的方法线程等待wait()和通知notify()方法,这两个方法不是Thread类的,而是属于Object类。

方法的方法签名:



当一个对象实例调用了wait()方法之后,当前线程就会在这个对象上等待。比如线程A中调用了obj.wait()方法,线程A就会停止继续执行而转为等待状态,等待状态持续到其他线程调用了obj.notify()或obj.notifyAll()为止。

当一个线程调用了obj.wait(),这个线程就会进入obj这个对象的等待队列中。obj.notify()会在这个对象的等待队列中随机选择一个线程进行通知唤醒;而notifyAll()则是通知唤醒等待线程队列中所有的线程。

还有就是wait和notify都必须包含在对应的synchronized语句中,无论是wait()还是notify()都需要先获取目标对象的一个监视器,并且执行之后都会释放这个监视器,如下图所示





wait()和notify()的例子:生产者消费者问题,代码如下

package com.bckj.Thread;/** * Created by Admin on 2017/6/12. *///仓库类public class Store {    private final int MAX_SIZE;  //仓库的最大容量    private int count;           //当前的仓库数量    public Store(int n){        MAX_SIZE = n;        count = 0;    }    //往仓库加货物的方法    public synchronized void add(){       //使用了wait()或notify()方法,需要加上syncronized关键字        while(count >= MAX_SIZE){          //否则可能会抛出java.lang.IllegalMonitorStateException            System.out.println("已经满了");            try{                this.wait();            }catch (InterruptedException e){                e.printStackTrace();            }        }        count++;        //打印当前仓库的货物数量        System.out.println(Thread.currentThread().toString()+" put"+count);        //仓库中已经有东西可以取了,则通知所有的消费者线程来拿        this.notifyAll();    }    //从仓库拿走货物的方法    public synchronized void remove(){        while(count <= 0){            System.out.println("空了");            try{                this.wait();            }catch (InterruptedException e){                e.printStackTrace();            }        }        //打印当前仓库的货物数量        System.out.println(Thread.currentThread().toString()+" get"+count);        count--;        //仓库还没装满,通知生产者添加货物        this.notify();    }    public static void main(String[] args) {        Store s = new Store(5);         //创建容量为5的仓库        //创建两个生产者和两个消费者        Thread pro = new Producer(s);        Thread con = new Consumer(s);        Thread pro2 = new Producer(s);        Thread con2 = new Consumer(s);        pro.setName("producer");        con.setName("consumer");        pro2.setName("producer2");        con2.setName("consumer2");        //启动各个线程        pro.start();        pro2.start();        con.start();        con2.start();    }}class Producer extends Thread{          //生产者线程类    private Store s;    public Producer(Store s){        this.s = s;    }    public void run(){      //线程方法        while(true){        //永久循环            s.add();        //往仓库加货物            try{                Thread.sleep(1000);            }catch (InterruptedException e){                e.printStackTrace();            }        }    }}class Consumer extends Thread{          //消费者线程类    private Store s;    public Consumer(Store s){        this.s = s;    }    public void run(){      //线程方法        while(true){        //永久循环            s.remove();        //往仓库取走货物            try{                Thread.sleep(1500);            }catch (InterruptedException e){                e.printStackTrace();            }        }    }}

执行结果:





原创粉丝点击