线程通信

来源:互联网 发布:阿里云 免费开通码 编辑:程序博客网 时间:2024/05/21 01:59

在现实应用中,很多时候,都需要去控制多个线程按照一定的次序去访问同一个共享的资源,比如生产–消费的经典案例
Java中提供3个重要的方法解决线程间的通信问题,这三个方法分别是wait();notify();notifyAll();
下面是一个生产苹果和消费苹果的案例,每次放入篮子中5个苹果之后,再从篮子中一个个取出,再放入,再取出,依次循环4轮;

import java.util.LinkedList;public class ProductConsumeDemo {    public static void main(String[] args) {        Basket basket = new Basket();        Productor productor = new Productor(basket);        productor.start();        Consumer consumer = new Consumer(basket);        consumer.start();    }}class Productor extends Thread{    private Basket basket=null;    public Productor(Basket basket) {        this.basket=basket;    }    @Override    public void run() {        basket.pushApple();    }}class Consumer extends Thread{    private Basket basket =null;    public Consumer(Basket basket){        super();        this.basket=basket;    }    @Override    public void run() {        basket.popApple();    }}//篮子class Basket{    private LinkedList<Apple> basket = new LinkedList<>();    //放四轮苹果    public synchronized void pushApple(){        for (int i = 0; i < 20; i++) {            Apple apple = new Apple(i);            push(apple);        }    }    //取四轮苹果    public synchronized void popApple(){        for (int i = 0; i < 20; i++) {            pop();        }    }    //向篮子中放苹果,放5个,就通知消费者    private void push(Apple apple){        if (basket.size()==5) {            try {                wait();                //wait和sleep方法的区别就是wait需要调用notify或者notifyAll方法去唤醒                //sleep的话时间已过就会自动的醒来            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }//等待并释放当前的锁        }        try {            Thread.sleep(500);        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        basket.addFirst(apple);        System.out.println("生产苹果:"+apple.toString());        notify();//通知消费者来消费    }    //从篮子中取苹果,如果篮子中苹果味0个,就通知生产者    private  void pop(){        LinkedList<Apple> basket2 = basket;        if (basket2.size()==0) {            try {                wait();//等待生产者            } catch (InterruptedException e) {                // TODO Auto-generated catch block                e.printStackTrace();            }        }        try {            Thread.sleep(500); //等待的时间        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        Apple apple = basket.removeFirst();        System.out.println("吃掉苹果:"+apple.toString());        notify();  //通知生产者来生产    }}//苹果类class Apple{    private int id;    public Apple(int id){        this.id = id;    }    @Override    public String toString() {        // TODO Auto-generated method stub        return "苹果"+(id+1);    }}

这里写图片描述

0 0