0

I came across one question when I gone through a JMS book. Below is the code. My question is related to thread so I removed the unnecessary JMS code.

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();  
  }
}

In the above code why the author is invoking the constructor as a new thread. I tried invoking constructor as below and it gives same result

public static void main(String[] args) {
    new MessageConsumer();  
}

So is there any difference in the above two ways. I know creating a new Thread() will create a separate new thread. However, in this simple example for JMS, do I need to invoke the constructor as separate thread?

Angom
  • 721
  • 1
  • 11
  • 27
  • Since JMS is used for communication that is asynchronous from your main program, they are demonstrating how that would be used in a separate thread. But it's not clear to me from this example what would prevent your main program from terminating. – Yosef Weiner Sep 05 '15 at 21:31
  • For this code, making a new thread doesn't make sense unless you hate main thread and like to have stuffs with another thread not know as main. Maybe he will add more stuffs after creating jms stuffs with main method. –  Sep 05 '15 at 21:59
  • @SkinnyJ I checked the code by running it in debug mode, even though the main thread exits the program still continues to run, looks like the MessageListner has a separate thread. – Angom Sep 07 '15 at 18:18

1 Answers1

0

This is a thread anti-pattern called "The Leaking this-pointer" and shouldn't be used.

Granted, I am assuming (since you stripped out the JMS code) that the constructor is setting up the connection to JMS in order to receive messages in the onMessage() callback. This will involve exposing the this pointer to JMS in order for it know which callback to post the incoming messages to.

The bottom line is: The instance (this) of MessageConsumer is not ready to be exposed outside the class.

I suspect that the author's intention was to spawn a new thread for JMS so that the main thread can continue to do other stuff, otherwise the program won't be doing much else. But because of the anti-pattern, it shouldn't be used.

Here is an alternative pattern:

 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.
    }
 }

This way, you are free to create a MessageConsumer in any thread you like, but strarting the JMS connection will involve an extra invocation of setupConnection().

Never expose the this pointer from within the constructor.

Daniel
  • 4,033
  • 4
  • 24
  • 33