当我浏览JMS书时,我遇到了一个问题。下面是代码。 我的问题与线程有关,所以我删除了不必要的JMS代码。
public class MessageConsumer implements MessageListener{
public MessageConsumer(){ //Constructor
//configure JMS Connections
}
@Override
public void onMessage(Message message) {
//receive message
}
public static void main(String[] args) {
new Thread(){
@Override
public void run() {
new MessageConsumer();
}
}.start();
}
}
在上面的代码中,为什么作者将构造函数作为新线程调用。 我尝试调用构造函数如下,它给出了相同的结果
public static void main(String[] args) {
new MessageConsumer();
}
上述两种方式有什么不同。我知道创建一个新的Thread()会创建一个单独的新线程。但是,在这个简单的JMS示例中,我是否需要将构造函数作为单独的线程调用?
答案 0 :(得分:0)
这是一个名为“Leaking this-pointer”的线程反模式,不应该使用。
当然,我假设(因为你剥离了JMS代码)构造函数正在建立与JMS的连接,以便在onMessage()
回调中接收消息。这将涉及将this
指针暴露给JMS,以便它知道将传入消息发布到哪个回调。
底线是:this
的实例(MessageConsumer
)不已准备好在课堂外公开。
我怀疑作者的意图是为JMS生成一个新线程,以便主线程可以继续执行其他操作,否则程序将不会做太多其他事情。但由于反模式,不应该使用它。
这是另一种模式:
public class MessageConsumer implements MessageListener {
final JmsConnectionInfo connInfo; // or something.
public MessageConsumer(JmsConnectionInfo connInfo) {
this.connInfo = connInfo;
}
public void setupConnection() {
// Do JMS stuff here. In this method you can expose
// the 'this' pointer to JMS without problem.
}
@Override
public void onMessage (Message message) {
// Receive message here.
}
}
这样,您可以在任何您喜欢的线程中自由创建MessageConsumer
,但是对JMS连接进行转换将涉及setupConnection()
的额外调用。
永远不要在构造函数中公开this
指针。