一、建立執行緒
@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(5000);
} 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 = Executors.newFixedThreadPool(1);
Future<Integer> future = executor.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println("===task start===");
Thread.sleep(5000);
System.out.println("===task finish===");
return 3;
}
});
//這裡需要返回值時會阻塞主執行緒,如果不需要返回值使用是OK的。倒也還能接收
//Integer result=future.get();
System.out.println("main函式執行結束");
System.in.read();
}
三、CompletableFuture
使用原生的CompletableFuture實現非同步操作,加上對lambda的支援,可以說實現非同步任務已經發揮到了極致。
@Test
public void test2() throws Exception {
System.out.println("main函式開始執行");
ExecutorService executor = Executors.newFixedThreadPool(2);
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(new Supplier<Integer>() {
@Override
public Integer get() {
System.out.println("===task start===");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("===task finish===");
return 3;
}
}, executor);
future.thenAccept(e -> System.out.println(e));
System.out.println("main函式執行結束");
}
四、Spring的Async註解
使用spring實現非同步需要開啟註解,可以使用xml方式或者java config的方式。
xml方式:
<task:annotation-driven executor="executor" />
<task:executor id="executor"
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.setCorePoolSize(10); //核心執行緒數
executor.setMaxPoolSize(20); //最大執行緒數
executor.setQueueCapacity(1000); //佇列大小
executor.setKeepAliveSeconds(300); //執行緒最大空閒時間
executor.setThreadNamePrefix("fsx-Executor-"); //指定用於新建立的執行緒名稱的字首。
executor.setRejectedExecutionHandler(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);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("完成");
}
(2)AsyncResult
如果需要返回值,耗時方法返回值用AsyncResult包裝。
@Test
public void test4() throws Exception {
System.out.println("main函式開始執行");
Future<Integer> future=myService.longtime2();
System.out.println("main函式執行結束");
System.out.println("非同步執行結果:"+future.get());
}
@Async
public Future<Integer> longtime2() {
System.out.println("我在執行一項耗時任務");
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("完成");
return new AsyncResult<>(3);
}