1.概念 及 代码地址
概念:
事情之间相对独立,A、B、C三个事情各自执行,A执行完之后回调或者通知B,B执行完之后回调或者通知C,在各自拿到其他事情的结果之前,可以先处理自己那部分的事情,这个过程叫做异步。
代码地址:
study-thread/src/main/java/cn/zy/study/thread/threadAsyn
2.参考文章
1.实现异步的 8 种方式,收藏起来
https://mp.weixin.qq.com/s/S53SK-Yy7OPnm-S_CdtymA
2. Java8 异步非阻塞做法:CompletableFuture 两万字详解!
https://mp.weixin.qq.com/s/dTxicKhZq_BXwcMne8mq7g
3.异步的几种实现方式
1. 线程Thread
2. Future
3. 异步框架CompletableFuture *******
4. Spring注解@Async *******
5. Spring ApplicationEvent事件
6. 消息队列
7. 第三方异步框架,比如Hutool的ThreadUtil
8. Guava异步
4.列举用到的实践方式
4.1.Spring注解@Async
业务逻辑类
package cn.zy.study.thread.threadAsyn;
import cn.hutool.extra.spring.SpringUtil;
import cn.zy.study.common.utils.date.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
@Service
@Slf4j
public class TransctionService2 {
@Autowired
ShWhRepository shWhRepository;
@Autowired
AsyncService2 asyncService2;
@Transactional(rollbackFor = Exception.class)
public void serviceFallAsync1() throws Exception {
log.info("=======================TransctionService2 serviceFallAsync1 开始执行");
System.out.println("=======================线程名称:" + Thread.currentThread().getName());
ShWh shWh = new ShWh();
shWh.setOrgId(1000L)
.setWh("仓库代码")
.setWhName("仓库名称")
.setWhType("仓库类型")
.setValuationMode("计价方式")
.setStorageMode("存储方式")
.setIsUsed(true).setWhAttr("仓库属性")
.setEnabled(false)
.setCreateTime(DateUtils.getTimestamp())
.setCreateUser("6666")
.setUpdateUser("6666").setUpdateTime(DateUtils.getTimestamp());
shWhRepository.save(shWh);
Future<String> stringFuture = asyncService2.serviceFallAsync2();
stringFuture.get();
}
@Autowired
ThreadPoolTaskExecutor myTaskAsyncPool;
@Transactional(rollbackFor = Exception.class)
public void completableFuture() {
ShWh shWh2 = new ShWh();
shWh2.setOrgId(1000L)
.setWh("仓库代码")
.setWhName("仓库名称")
.setWhType("仓库类型")
.setValuationMode("计价方式")
.setStorageMode("存储方式")
.setIsUsed(true).setWhAttr("仓库属性")
.setEnabled(false)
.setCreateTime(DateUtils.getTimestamp())
.setCreateUser("6666")
.setUpdateUser("6666").setUpdateTime(DateUtils.getTimestamp());
shWhRepository.save(shWh2);
System.out.println("当前线程名称" + Thread.currentThread().getName());
CompletableFuture<ShWh> userFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程名称" + Thread.currentThread().getName());
PlatformTransactionManager txManager = SpringUtil.getBean(PlatformTransactionManager.class);
TransactionStatus txStatus = txManager.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED));
ShWh shWh = new ShWh();
shWh.setOrgId(111L)
.setWh("仓库代码")
.setWhName("仓库名称")
.setWhType("仓库类型")
.setValuationMode("计价方式")
.setStorageMode("存储方式")
.setIsUsed(true).setWhAttr("仓库属性")
.setEnabled(false)
.setCreateTime(DateUtils.getTimestamp())
.setCreateUser("6666")
.setUpdateUser("6666").setUpdateTime(DateUtils.getTimestamp());
shWh = shWhRepository.save(shWh);
try {
Thread.sleep(1000L);
int a = 1 / 0;
txManager.commit(txStatus);
} catch (Exception e) {
txManager.rollback(txStatus);
throw new RuntimeException(e);
}
return shWh;
}, myTaskAsyncPool);
CompletableFuture.allOf(userFuture).join();
System.out.println("130行代码执行");
System.out.println("执行完成");
}
}
异步方法类
package cn.zy.study.thread.threadAsyn;
import cn.hutool.extra.spring.SpringUtil;
import cn.zy.study.common.utils.date.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import java.util.concurrent.Future;
@Component
@Slf4j
public class AsyncService2 {
@Autowired
ShWhRepository shWhRepository;
@Async("myTaskAsyncPool")
public Future<String> serviceFallAsync1() throws Exception {
log.info("====================AsyncService2 serviceFallAsync1 开始执行");
System.out.println("=======================线程名称:" + Thread.currentThread().getName());
ShWh shWh = new ShWh();
shWh.setOrgId(2000L)
.setWh("仓库代码2")
.setWhName("仓库名称2")
.setWhType("仓库类型2")
.setValuationMode("计价方式2")
.setStorageMode("存储方式2")
.setIsUsed(true)
.setEnabled(false)
.setWhAttr("仓库属性2")
.setCreateTime(DateUtils.getTimestamp())
.setCreateUser("8888")
.setUpdateUser("8888")
.setUpdateTime(DateUtils.getTimestamp());
shWhRepository.save(shWh);
log.info("====================AsyncService2 serviceFallAsync1 执行结束");
return new AsyncResult<String>("serviceFallAsync1 success");
}
@Async("myTaskAsyncPool")
public void serviceFallAsync4() throws Exception {
log.info("====================AsyncService2 serviceFallAsync2 开始执行");
System.out.println("=======================线程名称:" + Thread.currentThread().getName());
PlatformTransactionManager txManager = SpringUtil.getBean(PlatformTransactionManager.class);
TransactionStatus txStatus = txManager.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED));
ShWh shWh = new ShWh();
shWh.setOrgId(2000L)
.setWh("仓库代码2")
.setWhName("仓库名称2")
.setWhType("仓库类型2")
.setValuationMode("计价方式2")
.setStorageMode("存储方式2")
.setIsUsed(true)
.setEnabled(false)
.setWhAttr("仓库属性2")
.setCreateTime(DateUtils.getTimestamp())
.setCreateUser("8888")
.setUpdateUser("8888")
.setUpdateTime(DateUtils.getTimestamp());
shWhRepository.save(shWh);
try {
int a = 1 / 0;
txManager.commit(txStatus);
} catch (Exception e) {
txManager.rollback(txStatus);
throw new RuntimeException();
}
log.info("====================AsyncService2 serviceFallAsync2 执行结束");
}
@Async("myTaskAsyncPool")
public Future<String> serviceFallAsync3() throws Exception {
log.info("====================AsyncService2 serviceFallAsync3 开始执行");
System.out.println("=======================线程名称:" + Thread.currentThread().getName());
ShWh shWh = new ShWh();
shWh.setOrgId(2000L)
.setWh("仓库代码2")
.setWhName("仓库名称2")
.setWhType("仓库类型2")
.setValuationMode("计价方式2")
.setStorageMode("存储方式2")
.setIsUsed(true)
.setEnabled(false)
.setWhAttr("仓库属性2")
.setCreateTime(DateUtils.getTimestamp())
.setCreateUser("8888")
.setUpdateUser("8888")
.setUpdateTime(DateUtils.getTimestamp());
shWhRepository.save(shWh);
int a = 1 / 0;
log.info("====================AsyncService2 serviceFallAsync3 执行结束");
return new AsyncResult<String>("serviceFallAsync3 success");
}
@Async("myTaskAsyncPool")
public Future<String> serviceFallAsync2() throws Exception {
log.info("====================AsyncService2 serviceFallAsync2 开始执行");
System.out.println("=======================线程名称:" + Thread.currentThread().getName());
PlatformTransactionManager txManager = SpringUtil.getBean(PlatformTransactionManager.class);
TransactionStatus txStatus = txManager.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED));
ShWh shWh = new ShWh();
shWh.setOrgId(2000L)
.setWh("仓库代码2")
.setWhName("仓库名称2")
.setWhType("仓库类型2")
.setValuationMode("计价方式2")
.setStorageMode("存储方式2")
.setIsUsed(true)
.setEnabled(false)
.setWhAttr("仓库属性2")
.setCreateTime(DateUtils.getTimestamp())
.setCreateUser("8888")
.setUpdateUser("8888")
.setUpdateTime(DateUtils.getTimestamp());
shWhRepository.save(shWh);
try {
int a = 1 / 0;
txManager.commit(txStatus);
} catch (Exception e) {
txManager.rollback(txStatus);
log.error("exception:{}", e.getMessage());
e.printStackTrace();
throw new RuntimeException();
}
log.info("====================AsyncService2 serviceFallAsync2 执行结束");
return new AsyncResult<String>("serviceFallAsync2 success");
}
}
junit测试类
package cn.zy.study.thread.threadAsyn;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@Slf4j
public class TransctionService2Test {
@Autowired
TransctionService2 transctionService2;
@Test
public void serviceFallAsyncTest1() throws Exception {
transctionService2.serviceFallAsync1();
}
@Test
public void completableFutureTest1() throws Exception {
transctionService2.completableFuture();
}
}
5.异步框架CompletableFuture 使用
@Transactional(rollbackFor = Exception.class)
public void completableFuture() {
ShWh shWh2 = new ShWh();
shWh2.setOrgId(1000L)
.setWh("仓库代码")
.setWhName("仓库名称")
.setWhType("仓库类型")
.setValuationMode("计价方式")
.setStorageMode("存储方式")
.setIsUsed(true).setWhAttr("仓库属性")
.setEnabled(false)
.setCreateTime(DateUtils.getTimestamp())
.setCreateUser("6666")
.setUpdateUser("6666").setUpdateTime(DateUtils.getTimestamp());
shWhRepository.save(shWh2);
System.out.println("当前线程名称" + Thread.currentThread().getName());
CompletableFuture<ShWh> userFuture = CompletableFuture.supplyAsync(() -> {
System.out.println("当前线程名称" + Thread.currentThread().getName());
PlatformTransactionManager txManager = SpringUtil.getBean(PlatformTransactionManager.class);
TransactionStatus txStatus = txManager.getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRED));
ShWh shWh = new ShWh();
shWh.setOrgId(111L)
.setWh("仓库代码")
.setWhName("仓库名称")
.setWhType("仓库类型")
.setValuationMode("计价方式")
.setStorageMode("存储方式")
.setIsUsed(true).setWhAttr("仓库属性")
.setEnabled(false)
.setCreateTime(DateUtils.getTimestamp())
.setCreateUser("6666")
.setUpdateUser("6666").setUpdateTime(DateUtils.getTimestamp());
shWh = shWhRepository.save(shWh);
try {
Thread.sleep(1000L);
int a = 1 / 0;
txManager.commit(txStatus);
} catch (Exception e) {
txManager.rollback(txStatus);
throw new RuntimeException(e);
}
return shWh;
}, myTaskAsyncPool);
CompletableFuture.allOf(userFuture).join();
System.out.println("130行代码执行");
System.out.println("执行完成");
}