java 中使用wait与notifyAll的奇怪的问题
import java.util.ArrayList;import java.util.List;import java.util.Queue;import java.util.concurrent.LinkedBlockingQueue;public class Producer { private final Queue<String> productQueue = new LinkedBlockingQueue<String> (); private final List<Consumer> consumers = new ArrayList<Consumer> (); public void addConsumer(Consumer c) { this.consumers.add(c); } public void notifyProductGenerated() { for(Consumer c : this.consumers) { c.notifyProductGenerated(); } } public static void main(String... args) { Producer producer = new Producer(); final Consumer consumer = new Consumer(producer.productQueue); producer.addConsumer(consumer); new Thread(new Runnable() { @Override public void run() { consumer.consume(); } }).start(); for(int i = 0; i < 100; i++) { try { Thread.sleep(1000 * 1); } catch(InterruptedException ex) { ex.printStackTrace(); } producer.productQueue.add("" + i); System.out.println("" + i + " made."); producer.notifyProductGenerated(); } }}class Consumer { private Queue<String> productQueue; public Consumer(Queue<String> productQueue) { this.productQueue = productQueue; } public synchronized void notifyProductGenerated() { notifyAll(); } public synchronized void consume() { String product = null; while(true) { product = productQueue.poll(); if(product == null) { try { wait(); continue; } catch (InterruptedException ex) { ex.printStackTrace(); return; } } try { Thread.sleep(1000 * 10); } catch(InterruptedException ex) { ex.printStackTrace(); return; } System.out.println("run out of product " + product); } }}
public void consume() { String product = null; int number=0; //计数器,到100时线程正常结束。 while(number<100) { try //把休眠等待放在同步块外。 { Thread.sleep(100*10); } catch(InterruptedException ex) { ex.printStackTrace(); } synchronized(this) //与notifyProductGenerated()共用同一同步对象。 { product = productQueue.poll(); if(product == null) { try { wait(); continue; //? } catch (InterruptedException ex) { ex.printStackTrace(); return; } }//end if(product == null) System.out.println("run out of product " + product); }//end synchronized block.
[解决办法]
看看我这个 刚写的
class Info{ private String value=null; private String key=null; private boolean flag=false; public synchronized void set(String value,String key) { if(flag) { try { super.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } this.setKey(key); this.setValue(value); flag=true; super.notify(); } public void setValue(String value) { this.value=value; } public void setKey(String key) { this.key=key; } public String getKey() { return this.key; } public String getValue() { return this.value; } public synchronized void get() { if(!flag) { try { super.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(this.getKey()+"-----------"+this.getValue()); flag=false; super.notify(); }}class SetRun implements Runnable{ private Info info=null; public SetRun(Info info) { this.info=info; } public void run() { boolean flag=false; for(int i=0;i<50;i++) { if(flag) { this.info.set("河南大学","henu.edu.cn"); flag=false; } else { this.info.set("百度","www.baidu.com"); flag=true; } } }}class GetRun implements Runnable{ private Info info=null; public GetRun(Info info) { this.info=info; } public void run() { for(int i=0;i<50;i++) { this.info.get(); } }}public class MyThread{ public static void main(String[] args) { Info info=new Info(); new Thread(new SetRun(info)).start(); new Thread(new GetRun(info)).start(); }}