1. 程式人生 > >SpringBoot2.0之非同步任務(async)和 java8 CompletableFuture的呼叫

SpringBoot2.0之非同步任務(async)和 java8 CompletableFuture的呼叫

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());
	}
	
}

方法執行結果分別如下: