场景
如果我们调用有三个方法,methodA,methodB,methodC,他们耗时:
methodA:2s
methodB: 3s
methodC:3s
如果是串行
public void testTime(){
methodA() //2s
methodB() //3s
methodC() //3s
}
如果串行化 结果就是 8s,如何提高响应速度?
并行:
@Slf4j
public class AsynchronousUtils {
private static final long defaultTimeout = 6;
static Map<String,Future> map = new ConcurrentHashMap<>();
static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10,
0L, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(1), new ThreadPoolExecutor.CallerRunsPolicy());
// 并行方法调用
public static <T,U,R> void doAsynchronousDeal(BiFunction<T,U,R> biFunction,T t,U u){
Callable<R> callable = ()->{
return biFunction.apply(t,u);
};
FutureTask<R> futureTask = new FutureTask<>(callable);
threadPoolExecutor.submit(futureTask);
map.put(Thread.currentThread().getName()+t+u,futureTask);
}
/**
* 阻塞方式
* @param t
* @param u
* @param <T>
* @param <U>
* @param <R>
* @return
*/
public static <T,U,R> R getValue(T t,U u){
String key = Thread.currentThread().getName() + t+u;
Future<R> future = map.get(key);
try {
if (future == null){
return null;
}
return future.get();
}catch (Exception e){
log.warn("获取异步结果发生异常",e);
}finally {
map.remove(key);
}
return null;
}
// 带超时时间的获取结果
public static <T,U,R> R getAsynchronousValueDefaultTimeout(T t,U u){
return getAsynchronousValue(t,u,defaultTimeout);
}
public static <T,U,R> R getAsynchronousValue(T t,U u,long waitTime){
String key = Thread.currentThread().getName() + t+u;
Future<R> future = map.get(key);
try {
if (future == null){
return null;
}
return future.get(waitTime,TimeUnit.SECONDS);
}catch (Exception e){
log.warn("获取异步结果发生异常",e);
}finally {
map.remove(key);
}
return null;
}
public static void main(String[] args) throws Exception {
long l = System.currentTimeMillis();
test();
Thread thread = new Thread(()-> test());
thread.start();
thread.join();
System.out.println(System.currentTimeMillis() - l);
}
private static void test() {
for (int i=0;i<20;i++){
AsynchronousUtils.doAsynchronousDeal(AsynchronousUtils::add,i,i+1);
}
for (int i=0;i<20;i++){
Integer result = AsynchronousUtils.getAsynchronousValueDefaultTimeout(i, i + 1);
System.out.println(Thread.currentThread().getName()+": "+i+"\t"+(i+1)+" : "+ result);
}
}
private static Integer add(int a,int b){
try {
Thread.sleep(1000);
}catch (Exception e){
}
return a+b;
}
}
执行结果:
40次执行,每次执行耗时一秒,如果是串行得到结果需要40秒,
该工具类执行结果耗时:
6秒
main: 0 1 : 1
main: 1 2 : 3
main: 2 3 : 5
main: 3 4 : 7
main: 4 5 : 9
main: 5 6 : 11
main: 6 7 : 13
main: 7 8 : 15
main: 8 9 : 17
main: 9 10 : 19
main: 10 11 : 21
main: 11 12 : 23
main: 12 13 : 25
main: 13 14 : 27
main: 14 15 : 29
main: 15 16 : 31
main: 16 17 : 33
main: 17 18 : 35
main: 18 19 : 37
main: 19 20 : 39
Thread-0: 0 1 : 1
Thread-0: 1 2 : 3
Thread-0: 2 3 : 5
Thread-0: 3 4 : 7
Thread-0: 4 5 : 9
Thread-0: 5 6 : 11
Thread-0: 6 7 : 13
Thread-0: 7 8 : 15
Thread-0: 8 9 : 17
Thread-0: 9 10 : 19
Thread-0: 10 11 : 21
Thread-0: 11 12 : 23
Thread-0: 12 13 : 25
Thread-0: 13 14 : 27
Thread-0: 14 15 : 29
Thread-0: 15 16 : 31
Thread-0: 16 17 : 33
Thread-0: 17 18 : 35
Thread-0: 18 19 : 37
Thread-0: 19 20 : 39
6051