Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带发射机的生产者-消费者_Java_Multithreading - Fatal编程技术网

Java 带发射机的生产者-消费者

Java 带发射机的生产者-消费者,java,multithreading,Java,Multithreading,这是我遇到的面试问题。我对多线程编程非常幼稚 问题是:有三个线程:生产者、消费者和发送者。生产者和发送者共享一个名为ProduceBuf的缓冲区。使用者和发送器共享名为ConsumeBuf的缓冲区。Producer每次创建一个对象并将其添加到ProduceBuf中。发送器从ProduceBuf抓取一个对象,对该对象执行一些操作,然后将其放入ConsumerBuf。使用者使用ConsumerBuf中的对象。 ProduceBuf最多可获得12个对象。ConsumerBuf最多可以获得6个对象 这是

这是我遇到的面试问题。我对多线程编程非常幼稚

问题是:有三个线程:生产者、消费者和发送者。生产者和发送者共享一个名为ProduceBuf的缓冲区。使用者和发送器共享名为ConsumeBuf的缓冲区。Producer每次创建一个对象并将其添加到ProduceBuf中。发送器从ProduceBuf抓取一个对象,对该对象执行一些操作,然后将其放入ConsumerBuf。使用者使用ConsumerBuf中的对象。 ProduceBuf最多可获得12个对象。ConsumerBuf最多可以获得6个对象

这是我的试穿:

public class AdvanceCP {

    public static void main(String[] args) {

         AdvanceCP ad = new AdvanceCP();
         ProduceBuf pb = ad.new ProduceBuf();
         ConsumeBuf cb = ad.new ConsumeBuf();

         Producer p = ad.new Producer(pb);
         Transmitter t = ad.new Transmitter(pb,cb);
         Consumer c = ad.new Consumer(cb);

         Thread tp = new Thread(p);
         Thread tt = new Thread(t);
         Thread tc = new Thread(c);

         tc.start();
         tt.start();
         tp.start();
    }

    class ProduceBuf {
        int index = 0;
        Integer[] buffer = new Integer[12];

        public synchronized void produce(){
            while(index == buffer.length){
                //buffer is full
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            int newInt = (int) (Math.random()*100);
            buffer[index] = newInt;
            System.out.println("Producing a new object."+newInt);
            index++;
            this.notify();
        }

        public synchronized Integer pop(){
            while(index==0) {
                try{
                    this.wait();
                } catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
            index--;
            System.out.println("Transmitting a new object."+buffer[index]);
            return buffer[index];
        }
    }


    class ConsumeBuf {
        int index = 0;
        Integer[] buffer = new Integer[6];

        public synchronized void push(Integer newint){
            while(index==buffer.length){
                //buffer is full
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            buffer[index] = 0-newint;
            System.out.println("Transmitted a new object."+buffer[index]);
            index++;

            this.notify();
        }

        public synchronized Integer pop(){
            while(index==0) {
                try{
                    this.wait();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
            index--;
            System.out.println("Consuming a new object."+buffer[index]);
            return buffer[index];
        }
    }

    class Producer extends Thread{
        ProduceBuf pb =null;
        Producer(ProduceBuf p){
            pb = p;
        }
        public void run(){
            while(true) {
                pb.produce();
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    class Transmitter extends Thread{
        ProduceBuf pb = null;
        ConsumeBuf cb = null;
        Transmitter(ProduceBuf p,ConsumeBuf c){
            pb = p;
            cb  =c;
        }
        public void run(){
            while(true){
                cb.push(pb.pop());
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    class Consumer extends Thread{
        ConsumeBuf cb = null;
        Consumer(ConsumeBuf c){
            cb=c;
        }
        public void run(){
            while(true){
            cb.pop();
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

}
但是,控制台输出看起来不像多线程:

Producing a new object.43
Transmitting a new object.43
Transmitted a new object.-43
Consuming a new object.-43
Producing a new object.39
Transmitting a new object.39
Transmitted a new object.-39
Consuming a new object.-39
Producing a new object.98
Transmitting a new object.98
Transmitted a new object.-98
Consuming a new object.-98
Producing a new object.64
Transmitting a new object.64
Transmitted a new object.-64
Consuming a new object.-64
Producing a new object.52
Transmitting a new object.52
Transmitted a new object.-52
Consuming a new object.-52
所以我试着调整这三个线程的睡眠时间。如果我将消费者的睡眠时间添加到500。程序在执行某些操作后会卡住:

 Producing a new object.77
Transmitting a new object.77
Transmitted a new object.-77
Consuming a new object.-77
Producing a new object.83
Transmitting a new object.83
Transmitted a new object.-83
Producing a new object.46
Transmitting a new object.46
Transmitted a new object.-46
Producing a new object.28
Transmitting a new object.28
Transmitted a new object.-28
Producing a new object.72
Transmitting a new object.72
Transmitted a new object.-72
Producing a new object.25
Transmitting a new object.25
Transmitted a new object.-25
Producing a new object.94
Transmitting a new object.94
Transmitted a new object.-94
Producing a new object.63
Transmitting a new object.63
Producing a new object.64
Producing a new object.13
Producing a new object.14
Consuming a new object.-94
Producing a new object.63
Producing a new object.87
Producing a new object.80
Producing a new object.49
Producing a new object.85
Producing a new object.35
Producing a new object.16
Producing a new object.34
Producing a new object.14
Consuming a new object.-25
Consuming a new object.-72
Consuming a new object.-28
Consuming a new object.-46
Consuming a new object.-83

我不知道重点在哪里。作为一个多线程的初学者,我确信我忽略了一些东西,我感谢您的帮助。

问题是您没有通知
consumer.pop()
方法中的
push()
方法

所以它是这样的
1->有一个推入式消费者
2->缓冲区已满,因此推送处于等待状态
3->pop(消费线程)获取(删除)一个对象,但它不会告诉push这一点,因此这是您的问题,因为输出也说明了同样的问题。

所以你的流行音乐消费应该是这样的,(制作人的流行音乐有不同的故事)


还要注释掉所有
sleep()
内容,以获得更可靠的输出(限制运行/循环),或者将它们减少到较小的值并进行更改。

啊,我错过了notify()。太粗心了。所以解决方案本身是正确的,对吗?@FredXue看起来不错,但不是企业,对面试来说足够公平。非常感谢!给我一个关于企业解决方案的提示?^-^考虑到设计和实施良好的
MOA
系统,例如
public synchronized Integer pop(){
            while(index==0) {
                try{
                    this.wait();
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
            index--;
            System.out.println("Consuming a new object."+buffer[index]);
            Integer res=buffer[index];// 
            this.notify();//MISSED
            return res;
        }