简化版线程池
Worker Thread Pattern
worker是"是工人”的意思,在该模式中,工人线程(worker thread)会依次抓起一件工作来处理。当没有工作可作时,工人线程会听下来等待新的工作过来。
简单的实现是通过在运行时初始化(调用start方法)一组线程,在run方法不停的检查队列(或其他容器)是否有工作,下面是代码实现:
/**
* 工人线程
*/
class WorkerThread extends Thread {
private final ActivationQueue queue;
private volatile boolean shutdownRequested = false;
public WorkerThread(ActivationQueue queue) {
this.queue = queue;
}
public void shutdownRequest() {
shutdownRequested = true;
}
public void shutdownRequestNow() {
shutdownRequested = true;
interrupt();
}
public void run() {
while (!shutdownRequested) {
try {
FutureRequest request = queue.takeRequest();
request.execute();
} catch (InterruptedException e) {
}
}
}
Future模式
假设有一个执行起来需要花一些时间的方法,我们就不要等待执行结果出来了,而获取一张替代的“提货单”。因为获取提货单不需要花时间,这时这个“提货单”就是Future参与者。
代码示例:
future参与者接口
public abstract class Future<T> {
public abstract T getResultValue() throws InvocationTargetException;
public abstract T getResultValue(long timeout) throws InvocationTargetException;
}
future参与者实现
class RealFuture<T> extends Future<T> {
private T result;
private boolean ready = false;
private InvocationTargetException exception = null;
public synchronized void setResult(T result) {
this.result = result;
this.ready = true;
notifyAll();
}
public synchronized void setException(Throwable throwable) {
if (ready) {
return;
}
this.exception = new InvocationTargetException(throwable);
this.ready = true;
notifyAll();
}
public synchronized T getResultValue() throws InvocationTargetException {
while (!ready) {
try {
wait();
} catch (InterruptedException e) {
}
}
if (exception != null) {
throw exception;
}
return result;
}
public synchronized T getResultValue(long timeout) throws InvocationTargetException {
long startTime = System.currentTimeMillis();
while (!ready) {
try {
timeout = timeout - (System.currentTimeMillis() -startTime);
if(timeout <=0) return null;
wait(timeout);
} catch (InterruptedException e) {
}
}
if (exception != null) {
throw exception;
}
return result;
}
}
abstract class Request<T> {
protected final Runnable task;
protected Request(Runnable task) {
this.task = task;
}
public abstract void execute() throws InterruptedException;
}
public class FutureRequest<T> {
private Callable<T> callable;
private RealFuture<T> result;
public FutureRequest(Runnable task, RealFuture<T> result) {
this.callable = new RunnableAdapter<>(task,null);
this.result = result;
}
public FutureRequest(Callable callable, RealFuture<T> result) {
this.callable = callable;
this.result = result;
}
public void execute() throws InterruptedException{
try {
result.setResult(callable.call());
} catch (Exception e) {
result.setException(e);
}
}
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
}
Guarded Suspension模式
在家里正当换衣服的时候,忽然客厅门铃响了,原来是邮递员送行来了。因为衣服换到一半不能开门,所以就先说“请等我一下”,请邮递员在外面稍等。
代码实现可以参考RealFuture的getResultValue方法,当工人线程调用Request还没执行完时,设置RealFuture的ready为false,就会在对象的等待池中进行等待。
两阶段终止模式
将线程进行平常的处理的状态称为“作业中”。当希望结束这个线程时,则送出“终止请求”。接着这个线程,并不会马上结束,而会开始进行必要的刷新工作。这个状态称为“终止处理中”。从“作业中”改变成“终止处理中”是第一阶段。
“终止处理中”的状态时,不会进行平常的操作。虽然线程还在运行,但进行的是终止处理。直到终止处理结束后,才能真正结束线程。“终止处理中”的操作结束是第二阶段。
JDK7源码解析