I'll try to be brief. For a project of mine, I was tasked with developing a basic client-server program. The client has a basic GUI to work with and interact with the Server, the two interact via a middleman (Client Manager thread) and the Server dynamically creates Worker Manager threads tasked with creating and overseeing Worker threads.
The Client Manager creates Tasks based on the user's input on the GUI and sends them to the Server while also notifying the Worker Managers, who should be waiting by then. Once awake, Worker Managers will delegate tasks to their "minion" worker thread and the worker will take over. Worker Managers claim ownership over the Server's task list and take the first task for themselves (while also deleting the task from the Server's task list) and will then give it to their minion.
My issue, however, is that multiple workers are seemingly unable to read the full breadth of the task list. A single worker functions just fine so it appears to be a multi-threading/concurrency issue.
This is my Worker Manager's run method:
@Override
public void run() {
try {
while(true) {
if(!server.getTaskList().isEmpty() && !minion.isWorking()) {
try {
synchronized(server.getTaskList()) {
while(!server.getTaskList().isEmpty() && currenttask == null) {
currenttask = server.getTaskList().get(0);
server.getTaskList().remove(0);
}
}
if(!minion.isAlive()) {
minion = new Worker(this);
synchronized(minion) {
minion.setCurrenttask(currenttask);
minion.start();
}
}
minion.setCurrenttask(currenttask);
synchronized(minion) {
minion.setAlarmclock(true);
minion.notify();
minion.setWorking(true);
}
synchronized(this) {
while(!alarmclock)
this.wait();
alarmclock= false;
currenttask = null;
}
} catch (InterruptedException e) {
minion = new Worker(this);
minion.setCurrenttask(currenttask);
minion.start();
}
}
if(server.getTaskList().isEmpty())
synchronized(this) {
while(!alarmclock)
this.wait();
alarmclock= false;
currenttask = null;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
And this my Worker run method:
@Override
public void run() {
try {
while(true) {
if(currenttask != null) {
System.out.println(this + " new task " + currenttask );
if(manager.getServer().getTaskList().isEmpty())
System.out.println(this + "wtf ?");
work(currenttask);
isWorking = false;
}
else {
synchronized(this) {
while(!alarmclock)
this.wait();
alarmclock= false;
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
}
}
In my particular instance, I have 648 tasks at any given time but multiple workers/worker managers seem to "forget" about some of them, only processing 640 or 644 or 646 and then heading off to wait. I'm looking for anyone who may be able to point out if I made an obvious mistake here, given I'm not all that experience with concurrency and such.