您的位置:首页 > 编程语言 > Java开发

java线程:三种方式实现生产者消费者问题_2

2013-04-26 17:15 866 查看


java线程:三种方式实现生产者消费者问题_2

分类: java_线程2012-07-03
14:31 37人阅读 评论(0) 收藏 举报

上一种方式是采用synchronized关键字实现生产者消费者的问题,那是传统的做法,现在采用jdk1.5语法的新增的并发机制实现,以下是仓库类的具体代码实现(生产者类、消费者类类均不变,请参考上一篇文章:《三种方式实现生产者消费者_1》)。

[java] view plaincopy

<span style="font-family:Arial;">

/**

* 仓库:

* 先生产的先消费:使用队列的方式实现

*/

public class Storage {

public static final int MAX_SIZE = 100; // 仓库的最大货存

// 容器,为了使用方便,没有面向接口编程,使用LinkedList作为实现类

private LinkedList<Object> container = new LinkedList<Object>();

private Lock lock = new ReentrantLock(); // 互斥锁,相当于synchronized

private Condition getCondition = lock.newCondition();

private Condition putCondition = lock.newCondition();

// 往仓库中存放一个产品:

public void put(){

lock.lock();

try {

while(container.size() == MAX_SIZE){

putCondition.await();// 生产者等待,并让消费者唤醒

}

sop("put()等待结束,仓库现有数量为"+ container.size() +", 开始生产");

/*

* 试想一下:如果换成这种做法会有什么弊端:

* int size = storage.size();

* sop("put()等待结束,仓库现有数量为"+ size +", 开始生产");

* while(size == MAX_SIZE){

* putCondition.await();

* }

* ...

*/

container.addLast(new Object());

//通知消费者消费

getCondition.signal();

} catch(Exception e){

throw new RuntimeException(e);

} finally {

lock.unlock(); // 释放资源

}

}

// 从仓库中取出一个产品:

public void get(){

lock.lock();

try {

while(container.size() == 0){

// 消费者等待,并让生产者唤醒

getCondition.await();

}

sop("get()等待结束,仓库现有数量为"+ container.size() +", 开始消费");

Object obj = container.removeLast();

// 通知生产者生产

putCondition.signal();

Thread.sleep(1000);

} catch(Exception e){

throw new RuntimeException(e);

} finally {

lock.unlock();

}

}

private static void sop(Object obj){

System.out.println(obj);

}

}

</span>

以下是测试代码:

[java] view plaincopy

<span style="font-family:Arial;">public class Test {

public static void main(String[] args) {

Storage storage = new Storage();

Consumer con = new Consumer(storage);

Producer pro = new Producer(storage);

new Thread(pro).start();

new Thread(pro).start();

// new Thread(pro).start();

// new Thread(pro).start();

// new Thread(con).start();

new Thread(con).start();

new Thread(con).start();

new Thread(con).start();

new Thread(con).start();

}

}

</span>

测试结果:
get()等待结束,仓库现有数量为1, 开始消费

put()等待结束,仓库现有数量为0, 开始生产

put()等待结束,仓库现有数量为1, 开始生产

get()等待结束,仓库现有数量为2, 开始消费

get()等待结束,仓库现有数量为1, 开始消费

put()等待结束,仓库现有数量为0, 开始生产

put()等待结束,仓库现有数量为1, 开始生产

get()等待结束,仓库现有数量为2, 开始消费

get()等待结束,仓库现有数量为1, 开始消费

put()等待结束,仓库现有数量为0, 开始生产

put()等待结束,仓库现有数量为1, 开始生产

get()等待结束,仓库现有数量为2, 开始消费

put()等待结束,仓库现有数量为1, 开始生产

get()等待结束,仓库现有数量为2, 开始消费

get()等待结束,仓库现有数量为1, 开始消费

put()等待结束,仓库现有数量为0, 开始生产

get()等待结束,仓库现有数量为1, 开始消费

put()等待结束,仓库现有数量为0, 开始生产

get()等待结束,仓库现有数量为1, 开始消费

put()等待结束,仓库现有数量为0, 开始生产

get()等待结束,仓库现有数量为1, 开始消费
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: