Despite my experience with Java, I am not well-versed with concurrency. I wrote this thread pool that has a queue of tasks. Please ignore any signature choices, such as overuse of final. Thank you for your feedback!
public final class ThreadPool {
// Logging
//--------------------------------------------------
private static final Logger LOGGER = LoggerFactory.getLogger(ThreadPool.class);
// Constructors
//--------------------------------------------------
public ThreadPool(final int size, final boolean lazy) {
super();
this.size = size;
this.workers = new Worker[this.size];
this.queue = new LinkedBlockingQueue<>();
if(!lazy) createAndStartWorkers();
}
// Fields
//--------------------------------------------------
private volatile boolean initialized = false;
private final int size;
private final Worker[] workers;
private final BlockingQueue<Runnable> queue;
// Methods
//--------------------------------------------------
public final void schedule(final Runnable task) {
if(!initialized) createAndStartWorkers();
synchronized(queue) {
queue.add(task);
queue.notify();
}
}
public final void shutdown() {
for(int i = 0; i < size; i++) {
workers[i] = null;
}
}
public final int getSize() {
return size;
}
private void createAndStartWorkers() {
for(int i = 0; i < size; i++) {
workers[i] = new Worker();
workers[i].start();
}
initialized = true;
}
// Nested
//--------------------------------------------------
/**
* Worker thread.
*
* @author Oliver Yasuna
* @since 2.0.0
*/
private final class Worker extends Thread {
// Constructors
//--------------------------------------------------
private Worker() {
super();
}
// Overrides
//--------------------------------------------------
// Runnable
//
@Override
public final void run() {
Runnable task;
while(true) {
synchronized(queue) {
while(queue.isEmpty()) {
try {
queue.wait();
} catch(final InterruptedException e) {
LOGGER.warn("An error occurred while waiting for the queue.", e);
}
}
task = queue.poll();
}
try {
task.run();
} catch(final RuntimeException e) {
LOGGER.warn("Thread pool was interrupted due to an exception.", e);
}
}
}
}
}
final, yet I still make allpublicmethodsfinal. Same with constructors, which implicitly callsuper. \$\endgroup\$