java实现生产者-消费者

1213333 2014-03-01 07:54:39
class Message {
private String title;
private String content;
private boolean flag = true;

public synchronized void set(String title, String content) {
if (flag == false) {
try {
super.wait();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
else{
this.title = title;
this.content = content;}
this.flag = false;
super.notify();
}

public synchronized void get() {
if (flag == true) {
try {
super.wait();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
else{
System.out.println(this.title + "---->" + this.content);}
this.flag = true;
super.notify();
}
}

class Producer implements Runnable { // 定义生产者
private Message mes = null;

public Producer(Message mes) {
this.mes = mes;
}

public void run() {
for (int i = 0; i < 20; i++) {
if (i % 2 == 0) {
this.mes.set("**", "学习java");
} else {
this.mes.set("**", "学习C++");
}
}
}
}

class Consumer implements Runnable { // 定义消费者
private Message com = null;

public Consumer(Message com) {
this.com = com;
}

public void run() {
for (int i = 0; i < 20; i++) {
this.com.get();
}
}
}

public class ProducerConsumer {
public static void main(String[] args) throws Exception {
Message msg = new Message(); // 定义Message对象,用于保存和取出数据
new Thread(new Producer(msg)).start(); // 启动生产者线程
new Thread(new Consumer(msg)).start(); // 取得消费者线程
}
}
为什么加了这else就不行啊?去掉任意一个或全去掉就行啊,
谢谢啦。
...全文
335 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
kevinlifeng 2014-03-03
  • 打赏
  • 举报
回复
我运行了一下你的代码,有两个else的时候,不是死锁问题。虽然只运行打印出一条语句,可是程序运行完了,没有死锁。你的程序是这样运行的1.先生产者运行了第一个else{}因为flag=true,当执行完else块。flag=false的时候,这个时候,for()又调用set方法,这个时候就进入了set的if(){}块中,这个时候就等待线程来唤醒它。而且它已经释放资源。这个时候,get方法得到资源,执行这个时候flag=false的,这个没有异议吧!!这个时候,就就打印了一条记录出来了。然后就执行了flag=true的赋值,这个大家没有什么异议吧。不过问题就来了,super.nofity()大家以为这样就唤醒了生产者的set里面那个中断在if(){}块中的的那个线程,的确他是唤醒了它,可是,他还没有得到cpu的资源,所以他还要等一段时间。这个时候,get()又被执行了一次,这个时候flag=true的,这个大家可以理解吧!所以就会在get()方法的if(){}块中中断消费。这个时候,set里面的方法才被唤醒,然后执行flag=flag操作而且也nofity(),notify()方法和刚才的一样,是会唤醒消费者的get()块中中断的在if()块的方法,但是,他没有那么快得到资源,所以线程还是在继续调用set方法,这个时候flag=false,没有意见吧,这个时候,又在set的if()块中中断线程,这个时候。消费者终于得到资源,等了老半天,然后执行在if()块中中断段的程序,然后又执行了flag=true的操作,然后有nofity(),记得nofity()是唤醒了线程,不过线程还要得到资源。所以for在调用get的方法的时候,flag=true,然后就是继续中断消费者。希望对你有帮助。多看几遍,就明白我的意思了。谢谢
coolbamboo2008 2014-03-02
  • 打赏
  • 举报
回复
楼上的正解 多线程阻塞的时候就一定要想到唤醒
灰太狼A代 2014-03-02
  • 打赏
  • 举报
回复
楼上正解啊 和和
Tonny_wxm 2014-03-01
  • 打赏
  • 举报
回复
两个都加上 直接阻塞了当前线程 没人唤醒这个线程了
乔不思 2014-03-01
  • 打赏
  • 举报
回复
两个 都加上 就 死了。。。是不是? 没有唤醒其他进程

62,612

社区成员

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

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