package my.code.concurrency.c02.taskqueue2;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import my.code.concurrency.c02.taskqueue.common.ITaskManager;
import my.code.concurrency.c02.taskqueue.common.Request;
import my.code.concurrency.c02.taskqueue.common.TaskManagerStatus;
import my.code.concurrency.c02.taskqueue.common.Worker;
/**
* Handle request queue and pool of worker threads to carry process requests. In
* spike times some request will have to wait. See readme for full assessment.
* Use new Java 5 concurrency features, including higher level ones, notably
* {@link LinkedBlockingQueue}.
*/
public class TaskManager2 implements ITaskManager {
/**
* Core object, the queue itself.<br>
* Linked list is a better option then ArrayList,
*/
private BlockingQueue<Request> jobQueue = new LinkedBlockingQueue<Request>();
private int numberOfWorkers = 0;
private long totalReceived;
/**
* Keep references to workers
*/
private List<Worker> workerList = new ArrayList<Worker>();
public TaskManager2(int numberOfWorkers) {
this.numberOfWorkers = numberOfWorkers;
}
/**
* Client call
*
* @param request
*/
public void submit(Request request) {
// remove notifyAll() and sychronized
try {
jobQueue.put(request);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
totalReceived++;
}
/**
* Workers call. Take a job from a job queue.
*/
public Request take() {
Request workItem = null;
try {
workItem = jobQueue.take();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return workItem;
}
/**
* Call workers to process requests from the TM queue
*/
public void start() {
for (int i = 0; i < numberOfWorkers; i++) {
Worker worker = new Worker(this, i);
workerList.add(worker);
new Thread(worker).start();
}
}
/**
* @return status information about internal processing, queue length,
*/
public synchronized TaskManagerStatus getStatus() {
TaskManagerStatus result = new TaskManagerStatus();
double[] progress = new double[workerList.size()];
int i = 0;
for (Worker worker : workerList) {
progress[i] = worker.getProgress();
i++;
}
result.workersProgress = progress;
result.queueLength = jobQueue.size();
result.totalReceived = totalReceived;
return result;
}
}