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();
未被通知的原因
答案 0 :(得分:1)
在notifyAll()
之前调用wait()
,因此&#34;信号&#34;迷路了。这就是使用wait / notify时需要条件变量的原因。
boolean produced = false;
// In producer
produced = true;
asd.notifyAll();
// in consumer
while(!produced)
wait();
答案 1 :(得分:0)
关于您的代码的评论很少。
消费者类必须知道生产者类,这可以通过引入可以缓冲消息的第三个类来改进。
您是否考虑使用阻止队列或者您真的想要做什么? 生产者正在写入队列,而消费者只需从队列中读取而不知道谁实际写入队列。 (减少依赖性)。
如果将来您希望为同一个制作人提供多个消费者,您打算怎么做?
如果您想要一个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
}