3、并行程序
有没有方法可以在执行method1的时候同时执行method2,最后得到结果再进行处理?我们回到问题的出处,程序首先执行完method1得到结果result1之后,在执行method2获得结果result2,然后再按照result1和result2的结果来判定程序下一步的执行,最终我们得到的结果是result1和result2,然后再进行下一步操作,那么在我们得到result1和result2的时候,method1和method2其实是可以并发执行的,即我首先执行method1然后再执行mothod2,我不管他们的返回结果,只有在我要拿result1和result2进行操作的时候,程序才会调用Future.get()方法(这个方法会一直等待,直到结果返回),这是一种延迟加载的思想,与Hibernate中属性的延迟加载是一致的,即对于属性A,平时我是不用时不会进行赋值,只有我在用的时候,才执行SQL查询对其进行赋值操作。于是,我们得到了并发执行的程序形态。
Hibernate亦使用CGLIB来实现延迟加载,因此,我们可以考虑使用CGLIB的延迟加载类,将串行的程序并行化!
[java] view plain copyimport com.yang.domain.BaseResult;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.LazyLoader;
import org.junit.Test;
import java.lang.reflect.Method;
import java.util.concurrent.*;
/**
* @Description:
* @Author: yangzl2008
* @Date: 2016/1/9 19:39
*/
public class Parallel {
@Test
public void test02() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(2);
long start = System.currentTimeMillis();
// 开启线程执行
Future《BaseResult》 future1 = executorService.submit(new Task(this, “method1”, null));
// 不阻塞,正常执行,baseResult1是cglib的代理类,采用延迟加载,只有在使用的时候才调用方法进行赋值。
BaseResult baseResult1 = futureGetProxy(future1, BaseResult.class);
// 开启线程执行
Future《BaseResult》 future2 = executorService.submit(new Task(this, “method2”, null));
// 不阻塞,正常执行,baseResult1是cglib的代理类,采用延迟加载,只有在使用的时候才调用方法进行赋值。
BaseResult baseResult2 = futureGetProxy(future2, BaseResult.class);
// 这里要使用baseResult1和baseResult2
System.out.println(“baseResult1 is ” + baseResult1 + “\nbaseResult2 is ” + baseResult2);
long end = System.currentTimeMillis();
// 总耗时time = max(time1,time2)
System.out.println(“time cost is ” + (end - start));
}
private 《T》 T futureGetProxy(Future《T》 future, Class clazz) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
return (T) enhancer.create(clazz, new FutureLazyLoader(future));
}
/**
* 延迟加载类
* @param 《T》
*/
class FutureLazyLoader《T》 implements LazyLoader {
private Future《T》 future;
public FutureLazyLoader(Future《T》 future) {
this.future = future;
}
@Override
public Object loadObject() throws Exception {
return future.get();
}
}
public BaseResult method1() {
BaseResult baseResult = new BaseResult();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
baseResult.setCode(1);
baseResult.setMsg(“method1”);
return baseResult;
}
public BaseResult method2() {
BaseResult baseResult = new BaseResult();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
baseResult.setCode(1);
baseResult.setMsg(“method2”);
return baseResult;
}
class Task《T》 implements Callable《T》 {
private Object object;
private Object[] args;
private String methodName;
public Task(Object object, String methodName, Object[] args) {
this.object = object;
this.args = args;
this.methodName = methodName;
}
@Override
public T call() throws Exception {
Method method = object.getClass().getMethod(methodName);
return (T) method.invoke(object, args);
}
}
}
执行结果:
[plain] view plain copybaseResult1 is BaseResult{code=1, msg=‘method1’}
baseResult2 is BaseResult{code=1, msg=‘method2’}
time cost is 1057
评论
查看更多