线程还在等待

时间:2017-02-18 20:55:03

标签: java

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()进行沟通

pThread 完成通知作业后, cThread 会一直等待无限的时间。 任何想法,prod.sb.wait();

sb.notify();未被通知的原因

3 个答案:

答案 0 :(得分:1)

notifyAll()之前调用wait(),因此&#34;信号&#34;迷路了。这就是使用wait / notify时需要条件变量的原因。

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

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

答案 1 :(得分:0)

关于您的代码的评论很少。

  1. 消费者类必须知道生产者类,这可以通过引入可以缓冲消息的第三个类来改进。

  2. 您是否考虑使用阻止队列或者您真的想要做什么? 生产者正在写入队列,而消费者只需从队列中读取而不知道谁实际写入队列。 (减少依赖性)。

  3. 如果将来您希望为同一个制作人提供多个消费者,您打算怎么做?

  4. 如果您想要一个BlockingQueue(或类似)

    的示例,请告诉我

答案 2 :(得分:0)

以下是使用队列在不同线程中共享数据的生产者/消费者的示例:

/**
 * 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
}