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
評論
查看更多