黑马程序员技术交流社区
标题:
多线程案例——生产者消费者
[打印本页]
作者:
水蛭31
时间:
2015-6-19 11:29
标题:
多线程案例——生产者消费者
目的:生产一个,消费一个代码如下:
class Resource//共享资源
{
private String name;
private int count=1;
private boolean flag=false;
public synchronized void set(String name){
if(flag){
try{this.wait();}
catch(Exception e){}
}
this.name=name+"....."+count++;
System.out.println(Thread.currentThread().getName()+"....生产...."+this.name);
flag=true;
this.notify();
}
public synchronized void out(){
if(!flag){
try{this.wait();}
catch(Exception e){}
}
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 Customer implements Runnable
{
private Resource res;
Customer(Resource res){
this.res=res;
}
public void run(){
while(true){
res.out();
}
}
}
class ThreadProCus
{
public static void main(String[] args)
{
Resource res=new Resource();
Producer pro=new Producer(res);
Customer cus=new Customer(res);
Thread t1=new Thread(pro);
Thread t2=new Thread(cus);
t1.start();
t2.start();
}
}
复制代码
但是一般来说, 实际开发是有多个线程来生产消费的,
1.png
(14.84 KB, 下载次数: 0)
下载附件
2015-6-19 11:19 上传
运行的话,就会有问题,
2.png
(7.39 KB, 下载次数: 1)
下载附件
2015-6-19 11:19 上传
。这样就不对了, 为啥?
原因:线程可能唤醒的是本方的线程, 而将前一个给覆盖了, 这时就需要将这个线程再次判断一下, 所以需要把if变成while循环。
而这样, 可能会将这些线程都给冻结了, 因此需要将notify(),改成notifyAll().
代码如下:
class Resource
{
private String name;
private int count=1;
private boolean flag=false;
public synchronized void set(String name){
while(flag){//用if判断, 数据错误, while循环,全部等待, 不是活着的, 冻结了
try{this.wait();}
catch(Exception e){}
}
this.name=name+"....."+count++;
System.out.println(Thread.currentThread().getName()+"....生产...."+this.name);
flag=true;
this.notifyAll();
}
public synchronized void out(){
while(!flag){
try{this.wait();}
catch(Exception e){}
}
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 ThreadProCus1
{
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(pro);
Thread t3=new Thread(con);
Thread t4=new Thread(con);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
复制代码
总结:
1,对于多个生产和消费:
为什么要定义while判断标记。
原因:让被唤醒的线程再一次判断标记。
2,为什么定义notifyAll().
因为需要将对方的线程唤醒。
因为只用notify(),容易出现只唤醒本方的线程的情况,导致程序中的所有的线程都在等待。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2