I have a monitor object in Java which is basically built like this, while skipping irrelevant code:
public class TasksQueue {
private final Lock tasksLock = new ReentrantLock();
private final Condition newTask = tasksLock.newCondition();
private final List<Task> taskList = new LinkedList<>();
public Task getNextTask(BufferState buffer){
tasksLock.lock();
//if conditions not met await
(!placeholder_check()){
try {
newTask.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
newTask = taskList.remove(0);
return newTask;
}
public void addNextTask(Task task){
tasksLock.lock();
taskList.add(task);
newAnyTask.signal();
tasksLock.unlock();
}
}
Currently two other classes have access to this object, one of which only takes items out of the queue, another only adds items to it and signals the first one in the process as seen in the code.
My question is - can I move both enqueuing end dequeuing operations to be taken care of by one class (the second object enqueuing through the first one), and will it cause a deadlock as the object will "hang" on the await and stop letting others enqueue items which will completely halt the queue, or will the two method calls be seen as "separate" objects waiting in the monitor for Java?
The code for checking the types of added tasks and reacting accordingly was omitted here since it's not the core of the problem.