2015-09-09 2 views
3

Это вопрос интервью, с которым я столкнулся. И я действительно наивна в многопоточном программировании.Производитель Потребитель с передатчиком

Возникает вопрос: есть три потока: производитель, потребитель и передатчик. Продюсер и передатчик совместно используют буфер под названием ProduceBuf. Потребитель и передатчик совместно используют буфер, называемый ConsumeBuf. Производитель создает объект и каждый раз добавляет его в ProduceBuf. Передатчик захватывает объект из ProduceBuf и делает кое-что на объекте, затем помещает его в ConsumeBuf. Потребитель потребляет объект в ConsumeBuf. И ProduceBuf может получить 12 объектов больше всего. ConsumeBuf может получить только 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(); 
       } 
      } 
     } 

    } 

} 

Однако выход консоли кажется, что это не действует, как multithreads:

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 

Я не знаю, где находится точка. Будучи новичком многопоточности, я уверен, что есть кое-что, что я пропускаю, и я ценю помощь.

ответ

1

Проблема в том, вы не сообщаете метод push() в consumer.pop() методе

Так это выглядит следующим образом
1-> Существует толчок в потребительском
2-> Буфер полон, так толчке переходит в состояние ожидания
3-> Поп (потребляет поток) получает (удаляет) объект, и он не говорит об этом, так что это ваша проблема, так как вывод говорит то же самое.

Так что ваш поп в потреблении будет таким, (поп продюсера имеет другую историю).

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; 
     } 

Также закомментируйте все sleep() вещи, чтобы получить более надежные выходы (ограничение ПУСК/петли) или уменьшить их до малых значений и изменяются.

+0

А, я пропустил уведомление(). Так небрежно. Таким образом, решение само по себе правильно, не так ли? –

+0

@FredXue выглядит правильно, но не предприятие, достаточно справедливое для интервью –

+0

Спасибо, очень! дать мне подсказку о корпоративном решении?^-^ –

Смежные вопросы