生产者消费者 -多线程

前提:生产者不断地生产产品,消费者取走生产者生产的产品。生产者生产出产品后将其放到一个区域之中,消费者从这个地方去除数据

分析: 1.是否设计多线程?是,生产者,消费者
         2.是否涉及到共享数据?有!考虑线程的安全
         3.此共享数据是谁?即为产品的数量
         4.是否设计线程的通信?存在生产者与消费者的通信
public class Clerk {

    //当前商品数量
    private int product = 0;

    public synchronized void addProduct() {//同步控制并发
        while (product >= 5) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        product++;
        System.out.println(Thread.currentThread().getName() + "生成了" + product + "产品");
        notifyAll();//唤起所有阻塞的多线程
        //notify 只能通知一个在等待的对象,其他在等待的对象不会通知,会导致多线程的并发问题

    }

    public synchronized void consumProduce() {
        while (product <= 0) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println(Thread.currentThread().getName() + "消费" + product + "产品");
        product--;
        notifyAll();

    }
}
public class Consumer implements Runnable {//消费者
    Clerk clerk;

    public Consumer(Clerk clerk){
        this.clerk = clerk;
    }
    @Override
    public void run() {
        System.out.println("消费者消费产品");
        while (true){
            clerk.consumProduce();
        }
    }
}
public class Product implements Runnable {//生产者
    Clerk clerk;

    public Product(Clerk clerk){
        this.clerk = clerk;
    }
    @Override
    public void run() {
        System.out.println("生产者生产产品");
        for(int i=0;i<10;i++){
            clerk.addProduct();
        }
    }
}
 多线程测试类:
public class TestProductConsume {

    public static void main(String args[]){
        Clerk clerk = new Clerk();
        for(int i = 0; i < 4;i++){
            Product p1 = new Product(clerk);
            Consumer c1 = new Consumer(clerk);
            Thread t1 = new Thread(p1);
            Thread t2 = new Thread(c1);
            t1.setName("生产者"+i);
            t2.setName("消费者"+i);
            t1.start();
            t2.start();
        }
    }
}

notify只会通知一个在等待的对象,而notifyAll会通知所有在等待的对象,并且所有对象都会继续运行

被wait的线程,想要继续进行的话,必须满足2个条件:

           1.经过有其他线程notify或notifyAll,并且当前线程被通知到

            2.经过和其他线程进行锁竞争,成功获取锁

猜你喜欢

转载自my.oschina.net/u/3098425/blog/1826080