I wrote a multithreaded program in which I am seeing some weird behavior. Below is the code.
class Task implements Runnable {
private Command command;
private BlockingQueue<Integer> existPool;
private BlockingQueue<Integer> newPool;
private int existId;
private int newId;
public Task(Command command, BlockingQueue<Integer> pool1, BlockingQueue<Integer> pool2) {
this.command = command;
this.existPool = pool1;
this.newPool = pool2;
}
public void run() {
if(command.getDataCriteria().equals(PDSLnPConstants.DATA_CRITERIA_PREVIOUS)) {
try {
// Getting existing id from the pool
existId = existPool.take();
attributeGetSetMethod(existId);
} catch (Exception e) {
getLogger().log(LogLevel.ERROR, e.getLocalizedMessage());
} finally {
// And releasing that existing ID for re-use
existPool.offer(existId);
}
}
//Something wrong happening here
else if(command.getDataCriteria().equals(PDSLnPConstants.DATA_CRITERIA_NEW)) {
try {
// Getting new id from the pool
newId = newPool.take();
attributeGetSetMethod(newId);
} catch (Exception e) {
getLogger().log(LogLevel.ERROR, e.getLocalizedMessage());
} finally {
// And releasing that new ID for re-use
newPool.offer(newId);
}
}
}
}
From the below code. above run method is getting called.
for (int i = startRange; i <= endRange; i++) {
availableExistingIds.add(i);
}
for (int n = newStartRange; n <= newEndRange; n++) {
availableNewIds.add(n);
}
BlockingQueue<Integer> existIdPool = new ArrayBlockingQueue<Integer>(11, false, availableExistingIds);
BlockingQueue<Integer> newIdPool = new ArrayBlockingQueue<Integer>(21, false, availableNewIds);
GUID_ID_MAPPING = new LinkedHashMap<Integer, LinkedHashMap<Integer, String>>();
long startTime = System.currentTimeMillis();
long endTime = startTime + (durationOfRun*60*1000L);
// Running for particular duration of time
while(System.currentTimeMillis() <= endTime) {
Command nextCommand = getNextCommandToExecute();
Task nextCommandExecutorRunnable = new Task(nextCommand, existIdPool, newIdPool);
executorService.submit(nextCommandExecutorRunnable); // Submit it for execution
}
Problem Statement:-
One weird thing that I have just noticed is- In the below else if loop if you see my above code in run method if the command.getDataCriteria() is Previous then also it gets entered in the else if block(which is for New) which shouldn’t be happening right as I am doing a .equals check? Why this is happening?
else if(command.getDataCriteria().equals(PDSLnPConstants.DATA_CRITERIA_NEW)) {
Update:-
Below is the image from my console.
in which you can clearly see, dataCriteria was New and it went to PREVIOUS block
If your code is really
Then it is not possible that both
...s can get executed. It doesn’t depend on synchronization, threads, a bad equals implementation, or anything else. There’s something else you don’t understand (is it really the same run() call that is in both?), or possibly something I don’t understand about your problem statement (which is pretty confusing).