黑马程序员--生产者和消费者模式
2015-06-06 13:09
405 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
在学习了毕老师的生产者消费者模式,下面写下关于生产者消费者模式的理解,生产者生产产品到资源类中,而消费者冲资源类中取出产品并消费,如果只开启一个生产者的线程,一个消费者的线程,不会出问题如果开启两个生产者,两个消费者就会出现问题代码如下面所示:
class ProducerConsumerDemo
{
public static void main(String[] args)
{
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
// t1 t2
public synchronized void set(String name)
{
if(flag)
try{this.wait();}catch(Exception e){}//t1(放弃资格) t2(获取资格)
this.name = name+"--"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
flag = true;
this.notify();
}
// t3 t4
public synchronized void out()
{
if(!flag)
try{wait();}catch(Exception e){}//t3(放弃资格) t4(放弃资格)
System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
flag = false;
this.notify();
}
}
class Producer implements Runnable
{
private Resource res;
Producer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.set("+商品+");
}
}
}
class Consumer implements Runnable
{
private Resource res;
Consumer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.out();
}
}
}
代码如上所示,这样如果启用四个线程,如果线程t1进来发现 flag为false,那么他就进行生产,而生产完后,将flag设置成true;通知t2, t2线程进来后发现flag为true,就进入挂起状态,t3进入后,发现flag为true 就进行消费,然后将flag变成false ,这样t4线程进来就会挂起,这样四个线程就全部挂起,程序停止,要解决这个问题就要将notify()改为notifyAll(),notifyAll()是通知全部线程,notify()只通知程序内线程,改为notifyAll()还是会出问题。假如改成notifyAll()
t1,进入发现flag为false 进进行生产,生产完,把flag变成了true,通知其他线程,假如t2进入 ,发现flag为true ,就会挂起,这时候t3进入,发现flag为true,就进行消费产品,然后将flag变成flag,这时候通知别的线程访问,这时候t2如果被唤起,则不会重新进行判断,就进行生产,造成t1制作的产品没法被消费,解决这个问题的方法是将if(flag)变成while(flag)这样,while循环在每次执行的 时候都会进行判断,就会消除了这种情况。
改正后的代码如下
class ProducerConsumerDemo
{
public static void main(String[] args)
{
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
/*
对于多个生产者和消费者。
为什么要定义while判断标记。
原因:让被唤醒的线程再一次判断标记。
为什么定义notifyAll,
因为需要唤醒对方线程。
因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。
*/
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
// t1 t2
public synchronized void set(String name)
{
while(flag)
try{this.wait();}catch(Exception e){}//t1(放弃资格) t2(获取资格)
this.name = name+"--"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
flag = true;
this.notifyAll();
}
// t3 t4
public synchronized void out()
{
while(!flag)
try{wait();}catch(Exception e){}//t3(放弃资格) t4(放弃资格)
System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
flag = false;
this.notifyAll();
}
}
class Producer implements Runnable
{
private Resource res;
Producer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.set("+商品+");
}
}
}
class Consumer implements Runnable
{
private Resource res;
Consumer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.out();
}
}
}
在学习了毕老师的生产者消费者模式,下面写下关于生产者消费者模式的理解,生产者生产产品到资源类中,而消费者冲资源类中取出产品并消费,如果只开启一个生产者的线程,一个消费者的线程,不会出问题如果开启两个生产者,两个消费者就会出现问题代码如下面所示:
class ProducerConsumerDemo
{
public static void main(String[] args)
{
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
// t1 t2
public synchronized void set(String name)
{
if(flag)
try{this.wait();}catch(Exception e){}//t1(放弃资格) t2(获取资格)
this.name = name+"--"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
flag = true;
this.notify();
}
// t3 t4
public synchronized void out()
{
if(!flag)
try{wait();}catch(Exception e){}//t3(放弃资格) t4(放弃资格)
System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
flag = false;
this.notify();
}
}
class Producer implements Runnable
{
private Resource res;
Producer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.set("+商品+");
}
}
}
class Consumer implements Runnable
{
private Resource res;
Consumer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.out();
}
}
}
代码如上所示,这样如果启用四个线程,如果线程t1进来发现 flag为false,那么他就进行生产,而生产完后,将flag设置成true;通知t2, t2线程进来后发现flag为true,就进入挂起状态,t3进入后,发现flag为true 就进行消费,然后将flag变成false ,这样t4线程进来就会挂起,这样四个线程就全部挂起,程序停止,要解决这个问题就要将notify()改为notifyAll(),notifyAll()是通知全部线程,notify()只通知程序内线程,改为notifyAll()还是会出问题。假如改成notifyAll()
t1,进入发现flag为false 进进行生产,生产完,把flag变成了true,通知其他线程,假如t2进入 ,发现flag为true ,就会挂起,这时候t3进入,发现flag为true,就进行消费产品,然后将flag变成flag,这时候通知别的线程访问,这时候t2如果被唤起,则不会重新进行判断,就进行生产,造成t1制作的产品没法被消费,解决这个问题的方法是将if(flag)变成while(flag)这样,while循环在每次执行的 时候都会进行判断,就会消除了这种情况。
改正后的代码如下
class ProducerConsumerDemo
{
public static void main(String[] args)
{
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(con);
Thread t4 = new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
/*
对于多个生产者和消费者。
为什么要定义while判断标记。
原因:让被唤醒的线程再一次判断标记。
为什么定义notifyAll,
因为需要唤醒对方线程。
因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。
*/
class Resource
{
private String name;
private int count = 1;
private boolean flag = false;
// t1 t2
public synchronized void set(String name)
{
while(flag)
try{this.wait();}catch(Exception e){}//t1(放弃资格) t2(获取资格)
this.name = name+"--"+count++;
System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
flag = true;
this.notifyAll();
}
// t3 t4
public synchronized void out()
{
while(!flag)
try{wait();}catch(Exception e){}//t3(放弃资格) t4(放弃资格)
System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
flag = false;
this.notifyAll();
}
}
class Producer implements Runnable
{
private Resource res;
Producer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.set("+商品+");
}
}
}
class Consumer implements Runnable
{
private Resource res;
Consumer(Resource res)
{
this.res = res;
}
public void run()
{
while(true)
{
res.out();
}
}
}
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树
- [原创]java局域网聊天系统