2017-02-18 3 views
0
public class Communicate { 

    public static void main(String... args) { 
     Producer prod = new Producer(); 
     Consumer cons = new Consumer(prod); 

     Thread pThread = new Thread(prod, "ProducerThread"); 
     Thread cThread = new Thread(cons, "ConsumerThread"); 

     pThread.start(); 
     cThread.start(); 
    } 
} 
class Producer extends Thread { 

    StringBuffer sb; 
    Producer() {      //constructor 
     sb = new StringBuffer();  //allot memory 
    } 

    @Override 
    public void run() { 
     synchronized (sb) { 
      for (int i = 1; i <= 10; i++) { 
       try { 
        sb.append("daksh "); 
        Thread.sleep(100); 
        System.out.println("appending " + i); 
       } catch (InterruptedException ex) { 
       } 
      }//end of loop 

      //data production is over, so notify Consumer Thread 
      System.out.println("Done production"); 
      sb.notifyAll(); 
     } 
    } 
} 

class Consumer extends Thread { 

    Producer prod; 

    Consumer(Producer production) {   //constructor 
     this.prod = production; 
    } 

    @Override 
    public void run() { 
     System.out.println("sup"); 
     synchronized (prod.sb) { 
     //wait till the notification is received from the Producer thread. 
      try { 
       System.out.println("waiting"); 
       prod.sb.wait(); 
      } catch (InterruptedException ie) { 
      } 
      System.out.println("done"); 
     } 
     System.out.println(prod.sb); 
    } 
} 

Я пытаюсь сделать производить и потребителянити общаться с notify()Thread еще ждет

После PTHREAD делается с его уведомлением работы, то cThread продолжает ждать бесконечного количества времени. Любая идея, почему prod.sb.wait(); не является noitified по sb.notify();

+1

для синхронизации вам лучше использовать изменчивые атомные переменные. – efekctive

ответ

1

The notifyAll() вызывается перед wait(), так что "сигнал" потерян. Вот почему вам нужна переменная условия при использовании wait/notify.

boolean produced = false; 
// In producer 
produced = true; 
asd.notifyAll(); 

// in consumer 
while(!produced) 
    wait(); 
+0

Большое спасибо! Только один вопрос: я не совсем понял ответ: ** «Твое ожидание на одном объекте и уведомление другого» ** –

+0

получается, вы ** не ** даже должны объявлять его как 'volatile' :) –

+0

Это правда, не нужно волатильности. – Kayaman

0

Всего несколько комментариев относительно вашего кода.

  1. Класс потребителя должен знать класс производителя, и это можно улучшить, добавив третий класс, который может буферизовать сообщение.

  2. Рассматривали ли вы использование очереди блокировки или это действительно то, что вы хотите сделать? Производитель записывается в очередь, и потребитель должен просто читать из очереди, не зная, кто на самом деле записывается в очередь. (Меньшая зависимость).

  3. Если в будущем вы хотите иметь нескольких потребителей для того же производителя, как вы собираетесь это делать?

Позвольте мне знать, если вы хотите пример BlockingQueue (или аналогичный)

+0

Это был всего лишь примерный вопрос. Я новичок в этом. Пример ** BlockingQueue ** поможет: D и вы можете сообщить мне об этом ** третьем классе **? –

0

Вот пример Producer/Consumer с использованием очереди, чтобы обмениваться данными в различных потоках:

/** 
* Consumer class. 
* It consume 
* @author NourreddineHouari 
* 
*/ 
public static class Consumer { 

    /** 
    * Input queue. 
    */ 
    private BlockingQueue<String> intput; 

    private Thread t; 

    /** 
    * Constructor. 
    * @param input Input queue to read from. 
    */ 
    public Consumer(BlockingQueue<String> intput) { 
     // Input queue 
     this.intput = intput; 

     //Start consuming 
     t = new Thread(()->{ 
      while(true){ 
       // Read the data in the queue. 
       String data; 
       try { 
        // The take method will wait until something is 
        // available in the queue. 
        data = intput.take(); 
        //Consume your input data 
        System.out.println("Consumer [" + Thread.currentThread().getId() + "] : " + data); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Start consuming 
    */ 
    public void startConsuming(){ 
     //Start consumer process. 
     t.start(); 
    } 
} 

/** 
* Producer class. 
* @author NourreddineHouari 
* 
*/ 
public static class Producer { 

    /** 
    * Output queue. 
    */ 
    private BlockingQueue<String> output; 

    private Thread t; 

    public Producer(BlockingQueue<String> output) { 
     this.output = output; 
     Random r = new Random(); 
     //Start consuming 
     t = new Thread(()->{ 
      while(true){ 
       try { 
        //Wait random time 
        Thread.sleep(500 + r.nextInt(1000)); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 

       // Create dummy data 
       String data = Long.toString(System.currentTimeMillis()); 
       try { 
        this.output.put(data); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Start producing. 
    */ 
    public void startProducing(){ 
     //Start producer process. 
     t.start(); 
    } 
} 

/** 
* Sample. 
* @param args 
*/ 
public static void main(String[] args) { 

    //Declare the queue 
    BlockingQueue<String> queue = new ArrayBlockingQueue<>(10); 

    // Producer 
    Producer p = new Producer(queue); 

    // Consumers 
    Consumer c1 = new Consumer(queue); // The consumer and the producer don't know each others. 
    //Consumer c2 = new Consumer(queue); //Uncoment for multiple consumer 

    c1.startConsuming(); 
    p.startProducing(); 
    //c2.startConsuming(); //Uncoment for multiple consumers 
} 
Смежные вопросы