SpringBoot2.0之非同步任務(async)和 java8 CompletableFuture的呼叫
阿新 • • 發佈:2018-12-15
1.我們先介紹java8 的非同步呼叫:CompletableFuture
用CompletableFuture.supplyAsync()定義要執行的非同步任務
public class java8Async { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(10); // CompletableFuture.supplyAsync(),定義要執行的非同步任務 CompletableFuture.supplyAsync(new Supplier<String>() { @Override public String get() { // TODO Auto-generated method stub try { System.out.println("任務1"); // 睡眠1s TimeUnit.SECONDS.sleep(1); System.out.println("任務2"); } catch (Exception e) { e.printStackTrace(); } return "返回資料async"; } }, executor); // return System.out.println("任務執行完成"); } }
執行結果:
當非同步任務需要返回資料那怎麼辦呢?
用cupdResult.thenAccept(new Consumer<String>() , 重寫accept()方法去定義回撥函式
public class java8Async { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(10); // CompletableFuture.supplyAsync(),定義要執行的非同步任務 CompletableFuture<String> asyncResult = CompletableFuture.supplyAsync(new Supplier<String>() { @Override public String get() { // TODO Auto-generated method stub try { System.out.println("任務1"); // 睡眠1s TimeUnit.SECONDS.sleep(1); System.out.println("任務2"); } catch (Exception e) { e.printStackTrace(); } return "返回資料async"; } }, executor); // asyncResult.thenAccept(new Consumer<String>() , 重寫accept()方法去定義回撥函式 asyncResult.thenAccept(new Consumer<String>() { public void accept(String arg0) { System.out.println("return =" + arg0); } }); // return System.out.println("任務執行完成"); } }
執行結果:
2.我們介紹springboot的非同步任務:springboot給我們提供了註解方法,在啟動類上新增@EnableAsync註解,在需要用到非同步任務的實現方法上新增@Async註解,然後就可以用了,詳情如下:
啟動類:新增@EnableAsync註解
package com.async;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
* @ClassName: OtherApplication
* @Description: TODO()
* @author lixin( [email protected])
* @date 2018年10月13日 下午4:43:35
* @version V1.0
*/
@SpringBootApplication
@EnableTransactionManagement
@EnableAsync
public class OtherApplication {
public static void main(String[] args) {
SpringApplication.run(OtherApplication.class, args);
}
}
然後在你需要非同步呼叫的方法上添加註解
package com.async.boot;
import java.util.concurrent.Future;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @ClassName: AsyncAfterServiceImpl
* @Description: TODO()
* @author lixin([email protected])
* @date 2018年10月13日 下午4:50:38
* @version V1.0
*/
@Service
public class AsyncAfterServiceImpl implements AsyncAfterService{
@Transactional
@Override
@Async
public Future<String> asyncAfterOne() throws InterruptedException {
System.err.println("asyncAfterOne任務以執行");
return new AsyncResult<String>("asyncAfterOne執行完畢");
}
@Transactional
@Override
@Async
public Future<String> asyncAfterTwo() throws InterruptedException {
long currentTimeMillis = System.currentTimeMillis();
Thread.sleep(3000);
long currentTimeMillis1 = System.currentTimeMillis();
System.err.println("asyncAfterTwo任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms");
return new AsyncResult<String>("asyncAfterTwo執行完畢");
}
@Transactional
@Override
@Async
public Future<String> asyncAfterThree() throws InterruptedException {
long currentTimeMillis = System.currentTimeMillis();
Thread.sleep(6000);
long currentTimeMillis1 = System.currentTimeMillis();
System.err.println("asyncAfterThree任務耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms");
return new AsyncResult<String>("asyncAfterThree執行完畢");
}
}
然後是呼叫類:
package com.async.boot;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @ClassName: AsyncServiceImpl
* @Description: TODO()
* @author lixin([email protected])
* @date 2018年10月13日 下午4:54:15
* @version V1.0
*/
@Service
public class AsyncServiceImpl implements AsyncService{
@Autowired
private AsyncAfterService asyncAfterService;
@Transactional
@Override
public String asyncOne() throws InterruptedException {
long currentTimeMillis = System.currentTimeMillis();
asyncAfterService.asyncAfterOne();
asyncAfterService.asyncAfterTwo();
asyncAfterService.asyncAfterThree();
long currentTimeMillis1 = System.currentTimeMillis();
return "asyncAfter任務總耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms";
}
@Transactional
@Override
public String asyncTwo() throws InterruptedException, ExecutionException {
long currentTimeMillis = System.currentTimeMillis();
Future<String> two = asyncAfterService.asyncAfterTwo();
Future<String> three = asyncAfterService.asyncAfterThree();
String result = null;
while (true) {
if(two.isDone() && three.isDone()) {
System.err.println(two.get());
System.err.println(three.get());
// 兩個任務都呼叫完成,跳出迴圈
break;
}
Thread.sleep(1000);
}
long currentTimeMillis1 = System.currentTimeMillis();
result = "asyncAfter任務總耗時:"+(currentTimeMillis1-currentTimeMillis)+"ms";
return result;
}
}
然後是測試類:
package com.async;
import java.util.concurrent.ExecutionException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.async.boot.AsyncService;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = OtherApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EnableAutoConfiguration
public class AsyncTest {
@Autowired
private AsyncService asyncService;
@Test
public void asyncOne() throws InterruptedException {
System.err.println(asyncService.asyncOne());
Thread.sleep(8000);
}
@Test
public void asyncTwo() throws InterruptedException, ExecutionException {
System.err.println(asyncService.asyncTwo());
}
}
方法執行結果分別如下: