I am new to concurrent programming and I am facing few issues with the below code using Java threads.
Status Class (this class tracks the position availability):
public class Status {
private static Map<String, Boolean> positions = new HashMap<>();
static {
//Initially all positions are free (so set to true)
positions.put("A", true);
positions.put("B", true);
}
public synchronized void occupyOrClear(String position,
boolean status) {
positions.put(position, status);
}
public boolean isClear(String position) {
return positions.get(position);
}
}
MyThread Class:
public class MyThread implements Runnable {
private String[] positions;
private String customer;
public MyThread(String customer, String[] positions) {
this.positions = positions;
this.customer = customer;
}
private Status status = new Status();
public void run() {
for (int i = 0; i < positions.length;) {
String position = positions[i];
if (status.isClear(position)) {
// position occupied now
status.occupyOrClear(position, false);
System.out.println(position + " occupied by :"+customer);
try {
//my real application logic goes below (instead of sleep)
Thread.sleep(2000);
} catch (InterruptedException inteExe) {
System.out.println(" Thread interrupted ");
}
// Now clear the position
status.occupyOrClear(position, true);
System.out.println(position + " finished & cleared by:"+customer);
i++;
} else {
try {
Thread.sleep(1000);
} catch (InterruptedException inteExe) {
System.out.println(" Thread interrupted ");
}
}
}
}
}
ThreadTest Class:
public class ThreadTest {
public static void main(String[] args) {
String[] positions = { "A", "B"};
Status status = new Status();
Thread customerThread1 = new Thread(new MyThread(status, "customer1", positions));
Thread customerThread2 = new Thread(new MyThread(status, "customer2", positions));
Thread customerThread3 = new Thread(new MyThread(status, "customer3", positions));
customerThread1.start();
customerThread2.start();
customerThread3.start();
}
}
Even though I have used 'synchronized' I could notice that some times Thread3 is picking up prior to Thread2 and could you please help me to resolve this issue and to acheive the following results ?
(1) Always customerThread1 should take the positions first and then followed by customerThread2 and then customerThread3 (etc...)
(2) As soon as the A's position is freed by customerThread1, the position should be immediately picked up by customerThread2 (rather than customerThread2 and customerThread3 waiting till all positions are done by customerThread1).And as soon as customerThread2 finishes position 'A', then customerThread3 should pick it up, etc..
(3) As soon as the position (A, B, etc..) is freed/available, the next customerThread should pick it up immediately.
(4) The solution should avoid all race conditions