生产者与消费者----Java线程同步

[size=medium] 上篇日志所提到的Xiaonei Brush程序是存在Bug的,这个Bug即信息输出是不可预测的。什么问题呢?原来的程序通过一个线程来打印信息,该线程类为:PrintInfo(String msg,JTextArea area),msg是要输出的信息,而area是输出的dest.类声明为public PrintInfo extends Thread,当需要打印信息的时候,即通过:
new PrintInfo("我要打印一条信息",area);
实现,此种方式的弊端即在于线程调度时每个PrintInfo的运行时机是不可测的("你永远都不知道一个线程何时在运行"),即产生前面所说的Bug,信息输出时产生了错位。如:我有三条信息要输出
#1: new PrintInfo("This is 1st message",area);
#2: new PrintInfo("This is 2nd message",area);
#3: new PrintInfo("This is 3rd message",area);
当程序运行时,线程的运行顺序并不一定是按照#1,#2,#3来运行的,可能是#3,#2,#1,因此产生了错位.一个进一步的说明:第一个被调度的线程是#1,#1线程终止后并没有使#2进入运行状态而是将之挂起而运行#3.
  由此引出生产者消费者问题生产者与消费者问题可以被描述为:一个有限缓冲区和两类线程,它们是生产者和消费者,生产者把产品放入缓冲区,相反消费者便是从缓冲区中拿走产品。 生产者在缓冲区满时必须等待,直到缓冲区有空间才继续生产。消费者在缓冲区空时必须等待,直到缓冲区中有产品才能继续读取。
PrintInfo是消费者,它从缓冲区中取出消息将之打印.而主类以及Brush线程是生产者,它们产生消息并放入缓冲区.在参考相关资料后,我使用BlockingQueue来实现生产者消费者,方法很简单,具体地是使用了SynchronousQueue,SynchronousQueue实现了BlockingQueue接口,SynchronousQueue是一种阻塞队列,其中每个插入操作必须等待另一个线程的对应移除操作.
BlockingQueue queue=new SynchronousQueue<String>();
queue.put("放入消息");
String msg=queue.take();//take()获取并移除队列的头

******************************************************************

class Producer implements Runnable{
private final BlockingQueue<String> queue;

public Producer(BlockingQueue queue){
this.queue=queue;
}

public void run(){
...........要执行的代码
print(msg):
    ............
}

private void print(String msg){
try {
queue.put(msg);
} catch (InterruptedException e) {}
}
}

//消费者代码省略,和生产者区别不大,run方法:
while(true){
try{
while(true){
print(queue.take());
}
}catch (InterruptedException ex) {}
}

//测试类
BlockingQueue<String> queue=new SynchronousQueue<String>();
Producer p=new Producer(queue);
Consumer c=new Consumer(queue);
Thread tp=new Thread(p);
Thread tc=new Thread(c);
tp.run();
tc.run();

改写代码后,运行正常,信息输出不再错位.其他的解决方式留待以后再去看~
[/size]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值