title: Singleton pattern using its methods in different threads
body: <p>When designing a singleton class which can be used by multiple threads I run into the following challenge:</p>
  
  <p>There exits a main thread and another thread called client. The main method first gets an instance and afterwards the clients also get instances. And a client then executes a method of the singleton class my debug step through shows me that the main thread is interrupted to execute the method which is called by the client.</p>
  
  <p>How can I ensure that the client thread executes the method, without interrupting the main thread.</p>
  
  <p>Thanks in advance for efforts.</p>
  
  <p>Cheers
  Bob</p>
  
  <p>Edit:</p>
  
  <pre><code>public class SingletonEsperEngine {
  
      private static SingletonEsperEngine esperEngineObject;
      //Configuration for the Esper Engine
      private static Configuration cepConfig;
      //EPSServiceProvider represents the engine instance
      private static EPServiceProvider cep;
      private static EPRuntime cepRT;
      private static EPAdministrator cepAdm;
      private static boolean IsAlreadyInitialized;
      private static boolean IsNodeIdAvailable;
      public static ArrayList&lt;EPStatement&gt; cepStatement;
      public static ArrayList&lt;EPStatement&gt; cepLogInfo;
      public static ArrayList&lt;EPStatement&gt; cepFilterStatement;
      public static HashMap&lt;String, Integer&gt; mStatistics;
      public static HashMap&lt;Integer, Integer&gt; mNodeIds;
  
  
      //Experiment instantions
      private static JoinDebug joinDebugExperiment;
  
  
  
      private SingletonEsperEngine() {
      }
  
      /**
       * In order to prevent simultaneous invocation of the getter method
       * by 2 threads or more, we add the synchronized keyword to the method
       * declaration.
       *
       * @return SingletonEsperEngine
       */
      public static synchronized SingletonEsperEngine getInstance() {
          if (esperEngineObject == null) {
              esperEngineObject = new SingletonEsperEngine();
              IsAlreadyInitialized = false;
              IsNodeIdAvailable = false;
          }
  
          return esperEngineObject;
      }
  
      /**
       * InitEsperService
       *
       * Initialize the Esper Engine to accept MyriaNed messages.
       *
       * @return
       */
      public static synchronized int InitEsperService() {
  
      }
  
  public int dataToEsperEngine(String data, int numOfClient) {
          //Split string into timestamp and Myrianed Message 32 bytes
          String strTimestampClientSec = data.substring(0, 16);
          String strTimestampClientNano = data.substring(16, 32);
          String strTimestampSniffer = data.substring(32, 40);
          String message = data.substring(40);
          String joinBitMask = CONSTANT.JOIN_MESSAGE_bm.substring(2, 4) + CONSTANT.JOIN_MESSAGE_bm.substring(0, 2);
  
          HashMap&lt;String, Object&gt; Event = new HashMap&lt;String, Object&gt;();
  
              //It is an join message
  
              Event = putDataIntoEvent(message, evaluationMsgStruct, stamp, numOfClient);
              cepRT.sendEvent(Event, CONSTANT.JOIN_MESSAGE)
  
          if (CONSTANT.DEBUG) {
              printEventHashMap(Event, evaluationMsgStruct);
          }
  
          return CONSTANT.SUCCESS;
      }
  </code></pre>
  
  <p>The problem is caused when the client thread invokes <code>dataToEsperEngine()</code></p>
  
  <pre><code>public class Client implements Runnable {
  
      Socket mClientConnectionSocket;
      Connection mCon;
      //Seperate thread for every client, to handle the communication and event processing
      //ClientThread clientThread;
      public static Boolean stopClientThreads = false;
      public int mMode = CONSTANT.CLIENT_MODE_IDLE;
      public int mNumberOfThisClient;
      SingletonEsperEngine mEsperSupport;
      public Thread t;
      private String name;
  
  
  
      public void run() {
          String tmp = null;
          int idleTime = CONSTANT.SHORT_IDLE_TIME;
  
          while (!stopClientThreads) {
              try {
                  tmp = null;
                  switch (mMode) {
                      case CONSTANT.CLIENT_MODE_STOP:
                          //This will cause exiting of the while loop and terminates the thread
                          stopClientThreads = true;
                          return;
                      case CONSTANT.CLIENT_MODE_IDLE:
                          //Being lazy
                          break;
                      case CONSTANT.CLIENT_MODE_RECEIVE_STREAM:
                          tmp = receiveMessage();
                          if (tmp != null) {
                              System.out.println(tmp);
                              mEsperSupport.dataToEsperEngine(tmp, mNumberOfThisClient);
                          }
                          break;
                  }
  
                  //I am aware of the performance issues
                  //TODO rebuild with execution pool
                  this.t.sleep(idleTime);
  
              } catch (InterruptedException ex) {
                  Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
              }
  
          }
          return;
      }
  
      Client(Socket cC, String name) {
          //Save socket (=connection) into the client class
          mClientConnectionSocket = cC;
          gui.Debug.logThis("The server made a connection with: " + mClientConnectionSocket.getInetAddress());
  
          mEsperSupport = mEsperSupport.getInstance();
  
          this.name = name;
          mMode = CONSTANT.CLIENT_MODE_IDLE;
  
          t = new Thread(this);
          t.start();
  
          this.mNumberOfThisClient = Integer.parseInt(name);
  
          //Connect the input and output stream
          try {
              mCon = new Connection(new BufferedReader(new InputStreamReader(mClientConnectionSocket.getInputStream())), new PrintWriter(mClientConnectionSocket.getOutputStream()));
          } catch (IOException ex) {
              Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
          }
  
  
  
  
      }
  
      public String receiveMessage() {
          String tmp = null;
          try {
              tmp = mCon.cFrom.readLine();
          } catch (IOException ex) {
              Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
          }
  
          return tmp;
      }
  }
  </code></pre>