黑马程序员技术交流社区
标题:
生产者消费者问题JDK1.5新特性
[打印本页]
作者:
itheima_llt
时间:
2015-4-11 22:39
标题:
生产者消费者问题JDK1.5新特性
在JDK1.5之前,解决生产者和消费者问题,
用的是synchronized同步+while+notify();
但是这种方法很不安全,很容易让线程全部陷入无限等待状态。
于是我们改用notiyfyAll();来解决。
这样虽然解决了安全问题,但还是存在不足和安全隐患。
notifyAll方法唤醒了线程池中全部的线程,
这并不是我们想要的!
而且,同步套同步很容易发生死锁!
在JDK1.5中提供了显示的锁机制,完美的解决了上述问题。
它既可以做到只唤醒对方线程,而不唤醒己方线程,
又能够让一个锁绑定多个对象!
下面我们首先来看看JDK1.5新特性吧!
还是用2个生产者线程和2个消费者线程来展示。
import java.util.concurrent.locks.*;
//一、定义资源类
class Resource
{
private String name;//商品名称
private int count = 1;//商品编号
private boolean flag = false;//资源监视器
private Lock lock = new ReentrantLock();//建立一个锁对象,注意这里只有一把锁。注意,Lock是接口,不可以直接创建对象
private Condition condition_Pro = lock.newCondition();//建立与lock实例一起使用的Condition实例,生产者使用
private Condition condition_Con = lock.newCondition();//建立与lock实例一起使用的Condition实例,消费者使用
//设置商品名称,商品编号自增,并打印设置结果
public void set(String name)throws InterruptedException
{
lock.lock();//生产者线程获取锁。替换原来的synchronized
try
{
while(flag)//当资源监视器为true时,生产者线程等待
condition_Pro.await();//生产者线程等待,并throws InterruptedException
this.name = name;//获取商品名称
System.out.println(Thread.currentThread().getName()+"是生产者线程,生产的商品名称为:"+name+"商品编号为:"+count);
count++;//商品编号自增
flag = true;//把资源监视器改为true
condition_Con.signal();//只唤醒消费者线程
}
finally
{
lock.unlock();//一定要释放锁
}
}
//取出商品,并展示所取出的商品编号
public void get()throws InterruptedException
{
lock.lock();//消费者线程获取锁
try
{
while(!flag)//如果资源监视器为false,消费者线程等待,并抛出InterruptedException
condition_Con.await();
System.out.println(Thread.currentThread().getName()+"是消费者线程,消费的商品名称为:"+name+"商品编号为:......."+count);
flag = false;//把资源监视器改为false
condition_Pro.signal();//只唤醒生产者线程
}
finally
{
lock.unlock();//一定要释放锁
}
}
}
//二、定义生产者类
class Producer implements Runnable
{
private Resource r;//引用Resource类型变量r
//重载构造函数,避免建立多个对象
Producer(Resource r)
{
this.r = r;
}
//覆盖run方法
public void run()
{
try
{
while(true)//让生产者一直在生产
r.set("商品");
}
catch (InterruptedException e)
{
//暂不处理,以利于观察结果
}
}
}
//三、定义消费者类
class Consumer implements Runnable
{
private Resource r;//引用Resource类型变量r
//重载构造函数,和生产者线程使用同一资源对象
Consumer(Resource r)
{
this.r =r;
}
//覆盖run方法
public void run()
{
try
{
while(true)//让消费者一直取商品
r.get();
}
catch (InterruptedException e)
{
//暂不处理,方便观察
}
}
}
//四、定义测试类
class MyProducerConsumerDemo2
{
public static void main(String[] args)
{
Resource r = new Resource();//建立资源
Producer p = new Producer(r);//建立生产者
Consumer c= new Consumer(r);//建立消费者
Thread tp1 = new Thread(p);//建立生产者线程1
Thread tp2 = new Thread(p);//建立生产者线程2
Thread tp3 = new Thread(p);//建立生产者线程3
Thread tc1 = new Thread(c);//建立消费者线程1
Thread tc2 = new Thread(c);//建立消费者线程2
Thread tc3 = new Thread(c);//建立消费者线程3
tp1.start();//启动生产者线程1
tp2.start();//启动生产者线程2
tp3.start();//启动生产者线程3
tc1.start();//启动消费者线程1
tc2.start();//启动消费者线程2
tc3.start();//启动生产者线程3
}
}
复制代码
作者:
itheima_llt
时间:
2015-4-12 21:51
发帖都是0回复啊,囧!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2