黑马程序员技术交流社区
标题:
多线程问题(生产者消费者)-----生产与消费逻辑错误
[打印本页]
作者:
HM赵磊
时间:
2013-3-11 15:45
标题:
多线程问题(生产者消费者)-----生产与消费逻辑错误
class Resource
{
private String name;
private int num=1;
private boolean flag=false;
public synchronized void set(String name)
{
this.name=(name+"....."+(num++));
if(flag)
try
{
this.wait();
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"........."+"生产者"+"..."+this.name);
this.flag=true;
this.notify();
}
public synchronized void get()
{
if(!flag)
try
{
this.wait();
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"..."+"消费者"+"..."+this.name);
this.flag=false;
this.notify();
}
}
class Producer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.set("商品");
}
}
}
class Consumer implements Runnable
{
private Resource r;
Consumer(Resource r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.get();
}
}
}
class ProducerConsumerTest2
{
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(con);
t1.start();
t2.start();
}
}
结果是如下,问题出现在哪里?
file:///C:/Documents%20and%20Settings/Administrator/Application%20Data/Tencent/Users/452953881/QQ/WinTemp/RichOle/)U]X61B@D7]JC9OH%7D%7DAU0AI.jpg
作者:
HM李超
时间:
2013-3-11 16:07
class Resource
{
private String name;
private int num=1;
private boolean flag=false;
public synchronized void set(String name)
{
this.name=(name+"....."+(num++));
while(flag)
try
{
this.wait();
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"........."+"生产者"+"..."+this.name);
this.flag=true;
this.notify();
}
public synchronized void get()
{
while(!flag)
try
{
this.wait();
}
catch (Exception e)
{
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"..."+"消费者"+"..."+this.name);
this.flag=false;
this.notify();
}
}
class Producer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.set("商品");
}
}
}
class Consumer implements Runnable
{
private Resource r;
Consumer(Resource r)
{
this.r=r;
}
public void run()
{
while(true)
{
r.get();
}
}
}
class ProducerConsumerTest2
{
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(con);
t1.start();
t2.start();
}
}
复制代码
以上代码可以作为参考,你运行试试看,只要将 Resource类的判断flag标记的if改成while就可以了,
希望可以帮到你
作者:
爪哇攻城狮
时间:
2013-3-11 19:00
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();
}
}
}
复制代码
作者:
张晋瑜
时间:
2013-3-11 22:32
嗯,确实,必须是个循环
以下是我以前写的:
package synchronous;
/**
* 生产者与消费者问题
* 分析
* 仓库类Warehouse 生产者类Producer 消费者类Consumer
* 临界资源->仓库类Warehouse 临界区->存取产品的动作(代码)
* @author jin
*
*/
public class ProducerConsumer {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
WareHouse buffer=new WareHouse();
(new Producer(buffer)).start();
(new Consumer(buffer)).start();
}
}
class WareHouse{
private int product; // 仓库中的产品
private boolean isEmpty=true; // 标记仓库是否为空
public void put(int product_put){ //向仓库放入产品
// 若仓库不为空,则进入等待状态;
while(!isEmpty){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 若为空,则向仓库放入产品(放入了产品当能就要标记仓库不为空咯)并发出通知
this.product=product_put;
this.isEmpty=false;
notify();
}
public int get(){ //从仓库取出产品
// 若仓库为空,取产品这个动作的线程自然要进入等待状态了
while(isEmpty){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 若仓库不为空,返回产品(取出了产品仓库就空了,就要标记仓库为空)并发出通知
isEmpty=true;
notify();
return this.product;
}
}
class Producer extends Thread{
private WareHouse buffer; // 将要访问的临界资源
public Producer(WareHouse buffer) {
// TODO Auto-generated constructor stub
this.buffer=buffer;
}
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (buffer) {
for(int i=1; i<=5; i++){ // 假设生产5个产品:1、2、3、4、5
buffer.put(i);
System.out.println("存入产品:"+i);
}
}
}
}
class Consumer extends Thread{
private WareHouse buffer; // 将要访问的临界资源
public Consumer(WareHouse buffer) {
// TODO Auto-generated constructor stub
this.buffer=buffer;
}
@Override
public void run() {
// TODO Auto-generated method stub
synchronized (buffer) {
for(int i=1; i<=5; i++){ // 生产了5个产品,我们也就5次去拿产品
System.out.println("取出产品:"+buffer.get());
}
}
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2