When designing a singleton class which can be used by multiple threads I run into the following challenge:
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.
How can I ensure that the client thread executes the method, without interrupting the main thread.
Thanks in advance for efforts.
Cheers Bob
Edit:
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<EPStatement> cepStatement;
public static ArrayList<EPStatement> cepLogInfo;
public static ArrayList<EPStatement> cepFilterStatement;
public static HashMap<String, Integer> mStatistics;
public static HashMap<Integer, Integer> 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<String, Object> Event = new HashMap<String, Object>();
//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;
}
The problem is caused when the client thread invokes dataToEsperEngine()
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;
}
}
That has nothing to do with singletons, has it? You have to synchronize methods that shall not be interrupted, perhaps using synchronized
keyword. This is a difficult matter to answer in entirety, there are several books (such as Doug Lea ‘Concurrent Programming in Java’) you may consult. Apart from that, your question is not phrased quite precisely enough for me to add more detail.
And the 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.
That's absolutely impossible (unless both your main thread and the singleton class contain some fairly complex code to force tham to do that, in which case the solution is of course not to implement them that way). Most likely you are misinterpreting what the debugger displays.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With