java代码异步执⾏_Java实现异步调⽤
⼀、创建线程
@Test
public void test0() throws Exception {
System.out.println("main函数开始执⾏");
Thread thread =
new Thread(
new Runnable() {
@Override
public void run() {
System.out.println("===task start===");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("===task finish===");
}
});
thread.start();
System.out.println("main函数执⾏结束");
}
⼆、Future
jdk8之前的实现⽅式,在JUC下增加了Future,从字⾯意思理解就是未来的意思,但使⽤起来却着实有点鸡肋,并不能实现真正意义上的异步,获取结果时需要阻塞线程,或者不断轮询。
@Test
public void test1() throws Exception {
System.out.println("main函数开始执⾏");
ExecutorService executor = wFixedThreadPool(1);
Future future =
executor.submit(
new Callable() {
@Override
public Integer call() throws Exception {
System.out.println("===task start===");
Thread.sleep(5000);
System.out.println("===task finish===");
return 3;
}
});
// 这⾥需要返回值时会阻塞主线程,如果不需要返回值使⽤是OK的。倒也还能接收
//Integer ();
System.out.println("main函数执⾏结束");
ad();
}
三、CompletableFuture
使⽤原⽣的CompletableFuture实现异步操作,加上对lambda的⽀持,可以说实现异步任务已经发挥到了极致。
// 两个线程的线程池
ExecutorService executor = wFixedThreadPool(2);
// jdk1.8之前的实现⽅式
CompletableFuture<String> future =
CompletableFuture.supplyAsync(
new Supplier<String>() {
@Override
public String get() {
System.out.println("开始执⾏任务!");
try {
// 模拟耗时操作
Thread.sleep(20000);
System.out.println("我是⼀个特别耗时的任务");
} catch (Exception e) {
e.printStackTrace();
}
return "耗时任务结束完毕!";
}
},
executor);
/
/ 采⽤lambada的实现⽅式
future.thenAccept(e -> System.out.println(e + " ok"));
System.out.println("不等上⾯了,我先跑了"); //
四、Spring的Async注解
使⽤spring实现异步需要开启注解,可以使⽤xml⽅式或者java config的⽅式。xml⽅式:
pool-size="2" 线程池的⼤⼩
queue-capacity="100" 排队队列长度
keep-alive="120" 线程保活时间(单位秒)
rejection-policy="CALLER_RUNS" 对拒绝的任务处理策略 />
java⽅式:
@EnableAsync
public class MyConfig {
@Bean
public TaskExecutor executor(){
ThreadPoolTaskExecutor executor=new ThreadPoolTaskExecutor();
executor.tCorePoolSize(10); //核⼼线程数
executor.tMaxPoolSize(20); //最⼤线程数
executor.tQueueCapacity(1000); //队列⼤⼩
executor.tKeepAliveSeconds(300); //线程最⼤空闲时间
executor.tThreadNamePrefix("fsx-Executor-"); //指定⽤于新创建的线程名称的前缀。executor.tRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor;
}
}
(1)@Async
@Test
public void test3() throws Exception {
System.out.println("main函数开始执⾏");
myService.longtime();
System.out.println("main函数执⾏结束");
}
@Async
public void longtime() {
System.out.println("我在执⾏⼀项耗时任务");
try {
Thread.sleep(5000);
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("完成");
}
(2)AsyncResult
如果需要返回值,耗时⽅法返回值⽤AsyncResult包装。@Test
public void test4() throws Exception {
System.out.println("main函数开始执⾏");
Future future=myService.longtime2();
System.out.println("main函数执⾏结束");
System.out.println("异步执⾏结果:"+());
}
@Async
public Future longtime2() {
System.out.println("我在执⾏⼀项耗时任务");
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("完成");
return new AsyncResult<>(3);
}