关于多生产者多消费者的问题?

hlhdidi 2016-06-30 10:04:02
public class ProConTest {
public static void main(String[] args) {
Resource res=new Resource();
Producer pro1=new Producer(res);
Producer pro2=new Producer(res);
Consumer con1=new Consumer(res);
Consumer con2=new Consumer(res);
pro1.start();
pro2.start();
con1.start();
con2.start();
}
}
class Resource {
private boolean flag=true;
private int count;
public synchronized void product() {
while(!flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"生产"+(++count)+"只烤鸭");
flag=false;
notifyAll();
}
public synchronized void consume() {
if(flag) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+"消费"+(count)+"只烤鸭");
flag=true;
notifyAll();
}
}
class Producer extends Thread {
private Resource res;

public Producer(Resource res) {
super();
this.res = res;
}
public void run() {
while(true)
res.product();
}
}
class Consumer extends Thread{
private Resource res;
public Consumer(Resource res) {
super();
this.res = res;
}
public void run() {
while(true)
res.consume();
}
}

这是第一种形式,用的是标准的等待唤醒机制,下面是第二种形式...主要不同在于对于Resource生产消费的处理:
public class ProConTest {
public static void main(String[] args) {
Resource res=new Resource();
Producer pro1=new Producer(res);
Producer pro2=new Producer(res);
Consumer con1=new Consumer(res);
Consumer con2=new Consumer(res);
pro1.start();
pro2.start();
con1.start();
con2.start();
}
}
class Resource {
private boolean flag=true;
private int count;
public synchronized void product() {
if(flag) {
System.out.println(Thread.currentThread().getName()+"生产"+(++count)+"只烤鸭");
flag=false;
}

}
public synchronized void consume() {
if(!flag) {
System.out.println(Thread.currentThread().getName()+"消费"+(count)+"只烤鸭");
flag=true;
}
}
}
class Producer extends Thread {
private Resource res;

public Producer(Resource res) {
super();
this.res = res;
}
public void run() {
while(true)
res.product();
}
}
class Consumer extends Thread{
private Resource res;
public Consumer(Resource res) {
super();
this.res = res;
}
public void run() {
while(true)
res.consume();
}
}
可以看出第二种形式简化了.从结果来看,好像也没什么不同,那是不是说,多生产者多消费者问题实际上可以不用等待唤醒机制来实现呢?
...全文
679 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
hlhdidi 2016-06-30
  • 打赏
  • 举报
回复
引用 4 楼 qq_15915835 的回复:
[quote=引用 3 楼 hlhdidi 的回复:] [quote=引用 2 楼 qq_15915835 的回复:] 现在一般都用队列来做吧。常用的linkedblockqueue。
这个我还不是很清楚..我看到培训班视频自学的,请问我的第二种方法有什么问题吗?输出结果和分析都感觉没什么问题[/quote] 没啥问题啊。反正你锁住了,多线程,没啥意义。[/quote] 上楼的代码都不加synchronized后,会生产几个消费几个,而且有的时候消费会提前,如何解决??
hlhdidi 2016-06-30
  • 打赏
  • 举报
回复
引用 4 楼 qq_15915835 的回复:
[quote=引用 3 楼 hlhdidi 的回复:] [quote=引用 2 楼 qq_15915835 的回复:] 现在一般都用队列来做吧。常用的linkedblockqueue。
这个我还不是很清楚..我看到培训班视频自学的,请问我的第二种方法有什么问题吗?输出结果和分析都感觉没什么问题[/quote] 没啥问题啊。反正你锁住了,多线程,没啥意义。[/quote] 好吧..那请问我刚刚用BlockingQueue实现了一下多生产者多消费者问题,但是输出总是消费比生产还提前,而且一次性会生产消费很多,请问该如何解决这种问题?我下面的代码是有什么问题吗?


public class ProConTest {
    public static void main(String[] args) {
       Resource res=new Resource();
       Producer pro=new Producer(res);
       Consumer con=new Consumer(res);
       Thread t1=new Thread(pro);
       Thread t2=new Thread(con);
       t1.start();
       t2.start();
    }
}
class Resource {
	private String name;
	private int count;
	LinkedBlockingQueue queue=new LinkedBlockingQueue<>(1);
	public synchronized void produce() {
		count++;
		try {
			queue.put(count);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println("生产"+count+"烤鸭");
	}
	public synchronized void consume() {
		try {
			System.out.println("消费"+queue.take()+"烤鸭");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
class Producer implements Runnable{
	private Resource res;
	
	public Producer(Resource res) {
		super();
		this.res = res;
	}

	@Override
	public void run() {
		while(true)
		res.produce();
	}
	
}
class Consumer implements Runnable{
	private Resource res;

	public Consumer(Resource res) {
		super();
		this.res = res;
	}

	@Override
	public void run() {
		while(true)
		res.consume();
	}
	
}
qq_15915835 2016-06-30
  • 打赏
  • 举报
回复
引用 3 楼 hlhdidi 的回复:
[quote=引用 2 楼 qq_15915835 的回复:]
现在一般都用队列来做吧。常用的linkedblockqueue。

这个我还不是很清楚..我看到培训班视频自学的,请问我的第二种方法有什么问题吗?输出结果和分析都感觉没什么问题[/quote]

没啥问题啊。反正你锁住了,多线程,没啥意义。
hlhdidi 2016-06-30
  • 打赏
  • 举报
回复
引用 2 楼 qq_15915835 的回复:
现在一般都用队列来做吧。常用的linkedblockqueue。
这个我还不是很清楚..我看到培训班视频自学的,请问我的第二种方法有什么问题吗?输出结果和分析都感觉没什么问题
qq_15915835 2016-06-30
  • 打赏
  • 举报
回复
现在一般都用队列来做吧。常用的linkedblockqueue。
hlhdidi 2016-06-30
  • 打赏
  • 举报
回复
第一种实现是最标准的形式,但是第二种形式似乎也达到了预期的效果?我分析了一下,第二种机制,实际上就是线程判断标记后,如果不符合标记就会直接跳过什么都不执行,这样似乎也达到了预期的效果?

62,625

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧