package com.cactus.future;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TaskThreadPool extends ThreadPoolExecutor {
public TaskThreadPool(int arg0, int arg1, long arg2, TimeUnit arg3,
BlockingQueue<Runnable> arg4) {
super(arg0, arg1, arg2, arg3, arg4);
}
@SuppressWarnings("unchecked")
public <T> Future<T> submit(Callable<T> c, ResultListener listener) {
Callable<T> arg0 = (Callable<T>)Proxy.newProxyInstance(c.getClass().getClassLoader(), c.getClass().getInterfaces(),
new TaskInvokationHandler<T>(c, listener));
return super.submit(arg0);
}
private class TaskInvokationHandler<T> implements InvocationHandler {
private Callable<T> real;
private ResultListener listener;
public TaskInvokationHandler(Callable<T> real, ResultListener listener) {
this.real = real;
this.listener = listener;
}
public Object invoke(Object proxy, Method m, Object[] o)
throws Throwable {
if (m.getName().equals("call")) {
Object reault = null;
try {
reault = m.invoke(real, o);
TaskResult r = new TaskResult(null, reault, false);
listener.resultComing(r);
} catch (InvocationTargetException e) {
TaskResult r = new TaskResult(e.getCause(), reault, true);
listener.resultComing(r);
throw e;
}
}
return m.invoke(real, o);
}
}
private class TaskResult implements Result {
private Throwable e;
private Object o;
private boolean error;
public TaskResult(Throwable e, Object o, boolean error) {
super();
this.e = e;
this.o = o;
this.error = error;
}
public TaskResult() {
super();
}
public Throwable getE() {
return e;
}
public void setE(Throwable e) {
this.e = e;
}
public Object getO() {
return o;
}
public void setO(Object o) {
this.o = o;
}
public boolean isError() {
return error;
}
public void setError(boolean error) {
this.error = error;
}
public Throwable getException() {
return e;
}
public Object getResult() {
return o;
}
public boolean hasError() {
return error;
}
}
}