微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

线程间通信生产者消费者问题

如何解决线程间通信生产者消费者问题

我正在尝试使用以下代码的线程执行一些生产者消费者 poc,一轮后,两个线程都处于等待状态。 但我希望它们继续循环,其中一个线程不断增加计数器而其他线程不断减少。

有人可以建议我缺少什么吗?

public class ProducerConsumerWithThreads {

        synchronized void withdrawBoxConsumer() {
            if(Box > 0){
                Box --;
                System.out.println("Took one Box Now Boxes left "+  Box);
            }
            if(Box == 0) {
                System.out.println("Please put more Boxes");
                notify();
                try{wait();}catch(Exception e){
                    System.out.println("Exception occured" + e.fillInStackTrace());
                }
            } else {
                withdrawBoxConsumer();
            }
        }

        synchronized void putBoxProducer() {
            if(Box < 10){
                Box ++;
                System.out.println("Put one Box Now Boxes are "+  Box);
            }
            if(Box == 10) {
                System.out.println("Please Consume Boxes");
                notify();
                try{wait();}catch(Exception e){
                    System.out.println("Exception occured" + e.fillInStackTrace());
                }
            } else {
                putBoxProducer();
            }
        }

        public int Box = 5;

        public static void main(String[] args) throws InterruptedException {
            //pipeline of 10 Boxes
            //consumer takes one at a time .. till its empty

            int BoxLimit = 10;
            final int Box = 5;
            final ProducerConsumerWithThreads c=new ProducerConsumerWithThreads();

            new Thread(){
                public void run(){c.withdrawBoxConsumer();}
            }.start();
            new Thread(){
                public void run(){c.putBoxProducer();}
            }.start();
        }
}

我得到的输出是:

Took one Box Now Boxes left 4
Took one Box Now Boxes left 3
Took one Box Now Boxes left 2
Took one Box Now Boxes left 1
Took one Box Now Boxes left 0
Please put more Boxes
Put one Box Now Boxes are 1
Put one Box Now Boxes are 2
Put one Box Now Boxes are 3
Put one Box Now Boxes are 4
Put one Box Now Boxes are 5
Put one Box Now Boxes are 6
Put one Box Now Boxes are 7
Put one Box Now Boxes are 8
Put one Box Now Boxes are 9
Put one Box Now Boxes are 10
Please Consume Boxes

我期待它按照逻辑继续循环下去!有人可以帮忙吗?

解决方法

您的问题是一个非常基本的流程问题:当调用“notify”并且等​​待的线程再次启动时,该方法完成并且线程停止运行。

请注意,您的两个方法在同一个对象上同步,因此它们永远不会同时运行。例如。一个线程将获得监视器,并递增/递减该框,直到它最终等待。然后另一个线程会去,直到它等待。

在使用等待和通知时,您还有其他一些非常常见的问题。

    synchronized void withdrawBoxConsumer() {
        while( !Thread.currentThread().isInterrupted() ) { 
            if(box > 0){
                box --;
                System.out.println("Took one box now boxes left "+  box);
            }
            while(box == 0) {
                System.out.println("Please put more boxes");
                notifyAll();
                try{
                    wait();
                }catch(Exception e){
                    throw new RuntimeException(e);
                }
            } 
        }
    }

    synchronized void putBoxProducer() {
        while( !Thread.currentThread().isInterrupted() ) { 
            if(box < 10){
                box ++;
                System.out.println("Put one box now boxes are "+  box);
            }
            while(box == 10) {
                System.out.println("Please Consume boxes");
                notifyAll();
                try{
                    wait();
                }catch(Exception e){
                   throw new RuntimeException(e);
                }
            }
        }
    }
  • 我将其设为非递归,因为按照您的做法,堆栈会溢出。
  • 由于虚假唤醒,等待条件处于循环中。
  • 我切换到 notifyAll 通知只会唤醒一个等待线程,在这种情况下应该没问题,但最好是安全的。
  • box 理想情况下应该是一个并发类或 volatile,但由于您总是在同步方法中工作,所以应该没问题。
  • 同样,box++box-- 是竞争条件。
  • e.fillInStackTrace() 不是您想要使用的。
,
public class ProducerConsumerWithThreads {

        synchronized void withdrawBoxConsumer() {
            if(box > 0){
                box --;
                System.out.println("Took one box now boxes left "+  box);
            }
            if(box == 0) {
                System.out.println("Please put more boxes");
                notify();
                try{wait();}catch(Exception e){
                    System.out.println("Exception occured" + e.fillInStackTrace());
                }
            }
            withdrawBoxConsumer();
        }

        synchronized void putBoxProducer() {
            if(box < 10){
                box ++;
                System.out.println("Put one box now boxes are "+  box);
            }
            if(box == 10) {
                System.out.println("Please Consume boxes");
                notify();
                try{wait();}catch(Exception e){
                    System.out.println("Exception occured" + e.fillInStackTrace());
                }
            }
            putBoxProducer();
        }

        public int box = 5;

        public static void main(String[] args) throws InterruptedException {
            //pipeline of 10 boxes
            //consumer takes one at a time .. till its empty

            int boxLimit = 10;
            final int box = 5;
            final ProducerConsumerWithThreads c=new ProducerConsumerWithThreads();

            new Thread(){
                public void run(){c.withdrawBoxConsumer();}
            }.start();
            new Thread(){
                public void run(){c.putBoxProducer();}
            }.start();
        }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。