我发现了一些有趣的行为......我无法确定这是一个错误还是无能,但目前倾向于无能.
即使有消息等待,此代码也不会进入循环:
Message msg;
while ((msg = consumer.receiveNoWait()) != null) {
System.out.println(msg);
}
Run Code Online (Sandbox Code Playgroud)
此代码进入循环,注意空赋值:
Message msg = null;
while ((msg = consumer.receiveNoWait()) != null) {
System.out.println(msg);
}
Run Code Online (Sandbox Code Playgroud)
此代码在Windows 32bit上的Glassfish 3.1.1b10 HotSpot 1.6_26上运行.我想不出为什么第一个块不起作用的解释!
编辑/更新2011年7月13日:
首先,我开始停止Glassfish域并在每个请求的部署之间删除它,这仍然会发生:)
其次,我无法在Destination或Consumer上同步,因为这是Java EE代码.但是,我可以保证有可用的消息.其中大约有500个没有消费者.事实上,创建QueueBrowser告诉我有可用的消息!
第三,这个程序打印"WORKS!" 每次!!!哎呀!
public static void main(String[] args) {
Object obj;
if ((obj = getNotNull()) != null) {
System.out.println("worked!");
} else {
System.out.println("failed!");
}
}
static Object getNotNull() {
return new Object();
}
Run Code Online (Sandbox Code Playgroud)
最后,我说的是我自己的无能.;)
正如瑞安所说,这似乎是一种竞争条件。两个代码的字节码是相同的,除了一个额外的“astore”:
public static void code1() throws javax.jms.JMSException;
Code:
0: getstatic #2; //Field consumer:Ljavax/jms/MessageConsumer;
3: invokeinterface #3, 1; //InterfaceMethod javax/jms/MessageConsumer.receiveNoWait:()Ljavax/jms/Message;
8: dup
9: astore_0
10: ifnull 23
13: getstatic #4; //Field java/lang/System.out:Ljava/io/PrintStream;
16: aload_0
17: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
20: goto 0
23: return
public static void code2() throws javax.jms.JMSException;
Code:
0: aconst_null
1: astore_0
2: getstatic #2; //Field consumer:Ljavax/jms/MessageConsumer;
5: invokeinterface #3, 1; //InterfaceMethod javax/jms/MessageConsumer.receiveNoWait:()Ljavax/jms/Message;
10: dup
11: astore_0
12: ifnull 25
15: getstatic #4; //Field java/lang/System.out:Ljava/io/PrintStream;
18: aload_0
19: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/Object;)V
22: goto 2
25: return
}
Run Code Online (Sandbox Code Playgroud)
如果您想测试这个理论,请尝试以下代码:
Message msg;
String dummy = null;
while ((msg = consumer.receiveNoWait()) != null) {
System.out.println(msg);
}
Run Code Online (Sandbox Code Playgroud)
这是一个 noop,但字节码几乎与第二个代码相同(将“astore_0”更改为“astore_1”)。
顺便说一句,我的“receiveNoWait”结果很糟糕。我更喜欢“receive(smallTimeout)”,以避免缓冲区欠载等。