0

I am trying to create a Singleton class, which will be accessed from two other classes.Can anyone please tell me whats wrong with the following code? I am just not able to figure out!

import java.util.LinkedList;

public class MessageQueue {

    private static final LinkedList<ServerDataEvent> queue = new LinkedList<ServerDataEvent>();;

    private static MessageQueue messageQueue = null;

    /** A private Constructor prevents any other class from instantiating. */
    private MessageQueue() {
    }

    /** Static 'instance' method */
    public static MessageQueue getInstance() {
        if (MessageQueue.messageQueue == null) {
            System.out.println("Creating MessageQueue instance.");
            MessageQueue.messageQueue = new MessageQueue();
        }
        return MessageQueue.messageQueue;
    }

    public Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }
}

I am accessing the singleton object from other classes like this:

MessageQueue messageQueue = MessageQueue.getInstance();

There are no errors, but

System.out.println("Creating MessageQueue instance.");

is getting executed whenever I do

MessageQueue messageQueue = MessageQueue.getInstance();

EDIT 1

import java.util.LinkedList;

public class MessageQueue {

    private static final LinkedList<ServerDataEvent> queue = new LinkedList<ServerDataEvent>();;

    private static final MessageQueue messageQueue = new MessageQueue();

    /** A private Constructor prevents any other class from instantiating. */
    private MessageQueue() {
        System.out.println("problem...");
    }

    /** Static 'instance' method */
    public static MessageQueue getInstance() {
        return MessageQueue.messageQueue;
    }

    public Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }
}
14
  • What's wrong here is your first sentence: I am trying to create a Single ton class, which will be instantiated from two other classes. - you see the problem? It seems like a singleton is not what you want. Commented Jun 28, 2011 at 17:46
  • 1
    is there an error that occurs? is the singleton not created? Commented Jun 28, 2011 at 17:47
  • 1
    This is not thread-safe. Also, what is the problem referred to in the question title? Commented Jun 28, 2011 at 17:48
  • The logic for singleton seems to be correct. What problem do you see? Are you getting compile time errors or is the logic not working for you? Commented Jun 28, 2011 at 17:48
  • The basics of the code look fine, other than the fact it is not thread safe. What problems are you experiencing? Not getting an instance? Other? Commented Jun 28, 2011 at 17:49

6 Answers 6

4

First of all, you did not specify any errors you get. If you want to get help, you should give us as much information as you can.

Secondly, the best fool-proof way to create a singleton in Java is this:

public enum MySingleton {
    INSTANCE;

    //whatever methods you want to implement
}

and you access it like so: MySingleton.INSTANCE.whatever().

Sign up to request clarification or add additional context in comments.

1 Comment

There are no errors, but System.out.println("Creating MessageQueue instance."); is getting executed whenever I do MessageQueue messageQueue = MessageQueue.getInstance();
3

It is much better to define and instantiate your singleton object like this:

private static final MessageQueue messageQueue = new MessageQueue();

And then getInstance will be just:

public static MessageQueue getInstance() {
   return MessageQueue.messageQueue;
}

This way your singleton object is instantiated and will be thread safe because it is created by the class loader.

5 Comments

@Michael J. Lee: Thanks a lot, realized the typo and fixed :)
@anubhava: I did what you said. But I also added a simple System.out.println("inside constructor"); line in the constructor. After this if I do MessageQueue messageQueue = MessageQueue.getInstance(); from 2 different classes, I can see inside constructor both the times. Is it expected? Thanks.
Be aware that having the instance created by the thread loader can cause problems if creating the instance can throw an Exception. If it does, then the class will fail to be loaded and the error message will be... less than useful to people using your class (ie, you just get a message that it couldn't load any such class).
@Bhushan: Did you change your getInstance() method as well as I suggested above? As you can see construction is not even happening in getInstance() anymore so no matter how many times you call getInstance() it should never print inside constructor.
@RHSeeger: That's a valid point. Besides that another situation where instance created by the loader can't be used is when constructor needs some run time parameters to be passed.
1

A shorter version which is thread safe.

public enum MessageQueue {
    INSTANCE;

    private final Queue<ServerDataEvent> queue = 
        new ConcurrentLinkedQueue<ServerDataEvent>();    

    public void addEvent(ServerDataEvent event) { queue.add(event); }
}

or

public enum MessageQueue {
    ;

    private static final Queue<ServerDataEvent> queue = 
        new ConcurrentLinkedQueue<ServerDataEvent>();    

    public static void addEvent(ServerDataEvent event) { queue.add(event); }
}

Comments

0

would be easier if you did it this way...

public class MessageQueue {

    private static final MessageQueue INSTANCE= new MessageQueue();

    public static MessageQueue getINSTANCE() {
        return INSTANCE;
    }

    private MessageQueue() {
    }
}

Comments

0

What's the error that occurs? All I can see from this is you have two semicolons here:

private static final LinkedList<ServerDataEvent> queue = new LinkedList<ServerDataEvent>();;

Comments

0

Simplest method:

private static final MessageQueue messageQueue = new MessageQueue();

public static MessageQueue getInstance() {
   return MessageQueue.messageQueue;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.