2013-11-11 4 views
1

Я написал код, чтобы увидеть отношения производителей-производителей в Java, как показано ниже. Хотя программа работает нормально, я вижу несоответствие в выходе. Может кто-нибудь указать причину ниже несогласованности.Несоответствие в выходе для программы-производителя программы-производителя в Java

class ProdCons2 
{ 
    public static void main (String [] args) 
    { 
     Shared s = new Shared(); 
     new Producer (s).start(); 
     new Consumer (s).start(); 
    } 
} 

class Shared 
{ 
    private char c = '\u0000'; 
    private boolean writeable = true; 

    synchronized void setSharedChar (char c) 
    { 
     while (!writeable) 
     try 
     { 
      wait(); 
     } 
     catch (InterruptedException e) {} 

     this.c = c; 
     writeable = false; 
     notify(); 
    } 

    synchronized char getSharedChar() 
    { 
     while (writeable) 
     try 
     { 
      wait(); 
     } 
     catch (InterruptedException e) { } 

     writeable = true; 
     notify(); 

     return c; 
    } 
} 

class Producer extends Thread 
{ 
    private Shared s; 

    Producer (Shared s) 
    { 
     this.s = s; 
    } 

    public void run() 
    { 
     for (char ch = 'A'; ch <= 'Z'; ch++) 
     { 
      try 
      { 
       Thread.sleep ((int) (Math.random() * 1000)); 
      } 
      catch (InterruptedException e) {} 

      s.setSharedChar (ch); 
      System.out.println (ch + " produced by producer."); 
     } 
    } 
} 

class Consumer extends Thread 
{ 
    private Shared s; 

    Consumer (Shared s) 
    { 
     this.s = s; 
    } 

    public void run() 
    { 
     char ch; 
     do 
     { 
     try 
     { 
      Thread.sleep ((int) (Math.random() * 1000)); 
     } 
     catch (InterruptedException e) {} 

     ch = s.getSharedChar(); 
     System.out.println (ch + " consumed by consumer."); 
     } 
     while (ch != 'Z'); 
    } 
} 

Это дало мне выход, как показано ниже:

A produced by producer. 
    A consumed by consumer. 
    B produced by producer. 
    B consumed by consumer. 
    C produced by producer. 
    C consumed by consumer. 
    D produced by producer. 
    D consumed by consumer. 
    E produced by producer. 
    F produced by producer. 
    E consumed by consumer. 
    F consumed by consumer. 
    G produced by producer. 
    G consumed by consumer. 
    H produced by producer. 
    I produced by producer. 
    H consumed by consumer. 
    I consumed by consumer. 
    J produced by producer. 
    J consumed by consumer. 
    K produced by producer. 
    L produced by producer. 
    K consumed by consumer. 
    L consumed by consumer. 
    M produced by producer. 
    M consumed by consumer. 
    N produced by producer. 
    N consumed by consumer. 
    O produced by producer. 
    O consumed by consumer. 
    P produced by producer. 
    Q produced by producer. 
    P consumed by consumer. 
    Q consumed by consumer. 
    R produced by producer. 
    R consumed by consumer. 
    S produced by producer. 
    S consumed by consumer. 
    T produced by producer. 
    T consumed by consumer. 
    U produced by producer. 
    U consumed by consumer. 
    V produced by producer. 
    V consumed by consumer. 
    W consumed by consumer. 
    W produced by producer. 
    X produced by producer. 
    X consumed by consumer. 
    Y consumed by consumer. 
    Y produced by producer. 
    Z produced by producer. 
    Z consumed by consumer. 

Observe выход на P и Q:

P produced by producer. 
Q produced by producer. 
P consumed by consumer. 
Q consumed by consumer. 

Что является причиной того, что консоль не печатает:

P produced by producer. 
P consumed by consumer. 
Q produced by producer. 
Q consumed by consumer. 

ответ

3

Операции регистрации не являются частью синхронизированного раздела. Так что вполне возможно, чтобы эта последовательность событий:

  • производитель производит P, разблокирует потребитель
  • потребитель потребляет P, разблокирует производителю
  • производство производитель журналов P
  • производитель производит Q, разблокирует потребитель
  • производство журналов Q производство
  • потребительские журналы P потребление
  • потребитель потребляет Q
  • потребительские журналы Q расход

, который производит выходные данные, которые вы наблюдаете.

Если вы хотите, чтобы потребление всегда регистрировалось сразу после производства, то операторы протоколирования должны находиться внутри синхронизированных разделов кода.

1

Вместо того, чтобы писать wait()/notify() использовать стандартные классы совместимости от JDK: BlockingQueue интерфейс идеально подходит для Потребителя/Продюсера в многопоточном режиме.

+0

Хотя выход несовместим, он неверен. Я думаю, что System.out.println() не находится в правильном положении. Когда вызывается ch = s.getSharedChar(), ch получает значение P и сразу s.setSharedChar (ch) и оператор System.out.println() ниже, он вызывается и печатает Q, созданный производителем. И после этого P, потребляемый потребителем, печатается после метода получения потребительского потока. – anon

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