码迷,mamicode.com
首页 > 编程语言 > 详细

[笔记][Java7并发编程实战手册]2.4在同步代码中使用条件-生产者与消费者

时间:2015-08-08 18:15:44      阅读:223      评论:0      收藏:0      [点我收藏+]

标签:java   编程   并发   java 7   多线程   

说明

在并发编程中一个典型的问题是生产者–消费者问题。在程序中,有可能会需要用到两个线程通信的情况,比如生产者消费者中,获取一个共享数据,有就消费。没有就等待着生产者生产之后再继续消费。那么这个实现过程就可以使用wait();notify();notifyAll()来达到效果;
以上方法详细解说请查看: Java多线程系列–“基础篇”05之 线程等待与唤醒

例子

/**
 * Created by zhuqiang on 2015/8/8 0008.
 */
public class Client {
    public static void main(String[] args) {
        Storage st = new Storage();
        new Thread(new Producer(st), "小红").start();
        new Thread(new Consumer(st), "小名").start();
    }
}

/**
 * 仓库
 */
class Storage {
    private int maxSize = 10;  //仓库最大容量
    private LinkedList<Date> st = new LinkedList<Date>();  //仓库存储

    /** 生产 */
    public synchronized void producer() {
        while (st.size() > maxSize) {
            try {
                System.out.println(Thread.currentThread().getName() + " : 仓库满了,生产着等待生产中");
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
        st.push(new Date());
        System.out.println(Thread.currentThread().getName() + " : 生产了一个商品");
        this.notifyAll();  //唤醒其他等待的线程
    }

    /** 消费 */
    public synchronized void consumer() {
        while (st.size() == 0) { // 要注意这里, 进来一次,就要循环的判断如果一直没有库存,则一直等待,因为notifyAll()是唤醒所在在此监视器锁上等待的线程,有可能抢到资源的还是当前线程
            try {
                System.out.println(Thread.currentThread().getName() + " : 正在等待商品:当前商品数量:" + st.size());
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() + " : 消费商品:" + st.pop());
        this.notifyAll();  //唤醒其他等待线程(唤醒 生产者)
    }

    public int getMaxSize() {
        return maxSize;
    }

    public void setMaxSize(int maxSize) {
        this.maxSize = maxSize;
    }

    public LinkedList<Date> getSt() {
        return st;
    }

    public void setSt(LinkedList<Date> st) {
        this.st = st;
    }
}

/** 生产者 */
class Producer implements Runnable {
    private Storage st;

    public Producer(Storage st) {
        this.st = st;
    }

    @Override
    public void run() {
        /*for (int i = 1;i <=50;i++)*/
        while (true) {
            st.producer();
        }

    }
}

/** 消费者 */
class Consumer implements Runnable {
    private Storage st;

    public Consumer(Storage st) {
        this.st = st;
    }

    @Override
    public void run() {
        /*for (int i = 1;i <=50;i++)*/    //这里不能使用循环多少次来模拟,不然会出现(假死锁),假如生产者的循环次数先循环完,那么消费者的循环次数还没有循环完,而又没有商品了,那么消费者则一直等待。没有人唤醒
        while (true) {
            st.consumer();
        }
    }
}

说明:
上面示例大致逻辑:生产者不停的生产给仓库,仓库容量是10,达到最大容量则暂停生产;
消费者,不停的消费,仓库中有商品的时候才可以消费,否则等待;

版权声明:本文为博主原创文章,未经博主允许不得转载。

[笔记][Java7并发编程实战手册]2.4在同步代码中使用条件-生产者与消费者

标签:java   编程   并发   java 7   多线程   

原文地址:http://blog.csdn.net/mr_zhuqiang/article/details/47360569

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!