等待(wait)和通知(notify)

为了支持多线程之间的协作,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();
            }
        }
    }
}

执行结果:





发布了27 篇原创文章 · 获赞 7 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章