我有一个实现Observer&的课程。 Runnable如下(我知道这个例子可能很笨拙):
public class Triage implements Observer,Runnable{
Observable obsrvbl;
private BlockingQueue<String> messages;
volatile static boolean interrupted=false;
double updated;
Triage(Observable obsrvbl, BlockingQueue messages){
this.obsrvbl=obsrvbl;
this.messages = messages;
obsrvbl.addObserver(this);
}
public void update(Observable o, Object arg){
updated += ((Double)arg).doubleValue();
System.out.println("updated");
}
public void run(){
String msg;
while(!interrupted){
msg=messages.take();
if(msg!=null){
//do something with message
}
}
}
}
在Observable调用notifyObservers()的同时填充正在查看的队列。如果队列中没有任何内容,则会在Observer上成功调用update(),但如果Queue上有要处理的消息,则永远不会调用update()。这是预期的行为吗?
我见过this,但这似乎是一个不同的问题。
这是Observable - 有点做作:
public class Producer extends Observable implements Runnable {
volatile static boolean interrupted=false;
private BlockingQueue<String> quotes;
Producer(BlockingQueue quotes){
this.quotes=quotes;
}
public void run(){
String msg;
while(!interrupted){
msg=quotes.take();
if(msg!=null){
setChanged();
notifyObservers(Double.valueOf(3.0));
}
}
}
}
答案 0 :(得分:1)
弄清楚这有什么问题 - 我的疏忽。正如@slim在评论中建议的那样,两个队列是相同的,因此Triage的run()在Producer的run()之前消耗了该消息,因此没有得到通知。无论如何fwiw - 这是一个完整的工作示例:
public class Triage implements Observer,Runnable{
Observable obsrvbl;
private BlockingQueue<String> messages;
volatile static boolean interrupted=false;
Integer updated = 0;
private static Random rand = new Random(47);
Triage(Observable obsrvbl, BlockingQueue messages){
this.obsrvbl=obsrvbl;
this.messages = messages;
obsrvbl.addObserver(this);
}
public void update(Observable o, Object arg){
updated += ((Integer)arg);
System.out.println("Updated: " + updated);
}
public void run(){
String msg;
while(!interrupted){
try{
msg=messages.take();
System.out.println("Run: " + msg);
}catch(InterruptedException ie){}
}
}
public static void main(String[] args){
BlockingQueue<String> q1 = new LinkedBlockingQueue<String>();
BlockingQueue<String> q2 = new LinkedBlockingQueue<String>();
Producer p = new Producer(q1);
new Thread(p).start();
new Thread(new Triage(p,q2)).start();
for(int i=0;i<20;i++){
int next = rand.nextInt(10)*500;
System.out.println("Populating: " + next);
q1.add((Integer.valueOf(next)).toString());
q2.add((Integer.valueOf(next)).toString());
}
}
}
class Producer extends Observable implements Runnable {
volatile static boolean interrupted=false;
private BlockingQueue<String> quotes;
Producer(BlockingQueue quotes){
this.quotes=quotes;
}
public void run(){
String msg;
while(!interrupted){
try{
msg=quotes.take();
if(msg!=null){
System.out.println("Notifying: " + msg);
setChanged();
notifyObservers(Integer.valueOf(msg));
}
}catch(InterruptedException ie){}
}
}
}