Reputation: 852
I am writing multi-threading program which can be accessed from multiple user simultaneously and that program has to avoid race conditions.
Code / multi-threading :
public class DataProcessor implements Serializable, Runnable {
private static final long serialVersionUID = 1L;
public DataProcessor() {
}
@Override
public void run() {
process();
}
private void process() {
int iSize = 5;
for (int iCounter = 0; iCounter < iSize; iCounter++) {
DataKey objDataKey = new DataKey();
ArrayList<String> list = //..fetch data method ()
HashMap<String, String> hmPQdata = //..fetch data method ()
SendNForgotHelperThread helperThread = new SendNForgotHelperThread(objDataKey, list, hmPQdata);
Thread t = new Thread(helperThread);
t.start();
}
}
class SendNForgotHelperThread implements Runnable {
private ArrayList<String> list;
private HashMap<String, String> hmPQdata;
private DataKey objDataKey;
public SendNForgotHelperThread(DataKey objDataKey, ArrayList<String> list, HashMap<String, String> hmPQdata) {
this.list = list;
this.hmPQdata = hmPQdata;
this.objDataKey = objDataKey;
}
@Override
public void run() {
try {
// Option 1 : synchronized method - SendNForgotHelperThread class object locking
DataCollector objDataSenderM = new DataCollector();
objDataSenderM.synchronizedMethodStore(this.objDataKey, this.list, this.hmPQdata);
// Option 2 : synchronized block - SendNForgotHelperThread class object locking
synchronized (this) {
DataCollector objDataSender = new DataCollector();
objDataSender.store(this.objDataKey, this.list, this.hmPQdata);
}
// Option 3 : Class level locking
synchronized (SendNForgotHelperThread.class) {
DataCollector objDataSender = new DataCollector();
objDataSender.store(this.objDataKey, this.list, this.hmPQdata);
}
} catch (Exception iex) {
System.out.println("Exception in thread: " + iex.getMessage());
}
}
}
class DataCollector {
public void store(DataKey objDataKey, ArrayList<String> list, HashMap<String, String> hmPQdata) {
HashMap<String, String> retrivedValue = (HashMap<String, String>) MemCacheUtil
.retrieveFromMemCache(objDataKey.getKey());
retrivedValue.putAll(hmPQdata);
MemCacheUtil.addToMemCache(objDataKey.getKey(), retrivedValue, "expTime value");
// Sending data in queue
sendDataToQueue(objDataKey, list, hmPQdata);
}
synchronized void synchronizedMethodStore(DataKey objDataKey, ArrayList<String> list,
HashMap<String, String> hmPQdata) {
store(objDataKey, list, hmPQdata);
}
}
class DataKey {
private String key;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
}
public void sendDataToQueue(DataKey objDataKey, ArrayList<String> list, HashMap<String, String> hmPQdata) {
// sending data to queue
}
}
User 1 :
public class UserA {
public static void main(String[] args) {
DataProcessor objDataProcessor = new DataProcessor();
Thread thProcessorThread = new Thread(objDataProcessor, "PROCESSOR");
thProcessorThread.start();
}
}
User 2 :
public class UserB {
public static void main(String[] args) {
DataProcessor objDataProcessor = new DataProcessor();
Thread thProcessorThread = new Thread(objDataProcessor, "PROCESSOR");
thProcessorThread.start();
}
}
User A & B will be call DataProcessor thread at same time. It is clear that Option 1 & 2 will be face race conditions as they are locking object of that class / self class object locking and option 3 will provide lock on class level - if multiple user will access the program at same time then option 3 will slow the application and whole purpose of the multi-threading will go on toss.
Could any one please advise any read-up on how to handle this scenario.
Edit :
Could any one please help to handle race condition on SendNForgotHelperThread thread object - this thread being called from loop and for each loop new thread SendNForgotHelperThread being started.
Upvotes: 2
Views: 735
Reputation: 12817
You're passing two different instance of DataProcessor
to the threads in class UserA
and UserB
, if you start these main methods it will run normally. the race-condition won't occur in your application.
For race-condition to occur you have to pass the shared object, i.e. multiple threads to operate on a same object and the shared objects should have field/attribute to get shared between multiple threads
DataProcessor objDataProcessor = new DataProcessor();
Thread thProcessorThread1 = new Thread(objDataProcessor, "PROCESSOR-1");
thProcessorThread1.start();
Thread thProcessorThread2 = new Thread(objDataProcessor, "PROCESSOR-2");
thProcessorThread2.start();
Upvotes: 2