假设我有三个方法想要异步,在一个类中,有如下调用
Utils.insertUser();
Utils.insertAddress();
Utils.insertInformation();
Utils.selectAll()
首先,前三个方法是设置了@Async的注解方法,假设他是往数据库里面插入数据,第四个是把插入的数据查出来,数据来源就是前三个方法,这个方法没有@Async注解。
现在的问题是,由于前三个方法设置了@Async,导致前三个方法可能还未执行完毕,第四个查询方法就已经开始执行了,这样就没有意义了。所以,如何做到保证前三个方法异步执行,且全部执行完毕后,再执行第四个方法?
其实你可以不用 @Asyn,只是想要这三个操作并发执行而已
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
CountDownLatch latch = new CountDownLatch(3);
executorService.execute(() -> {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println("执行第一个操作");
} catch (InterruptedException e) {
} finally {
latch.countDown();
}
});
executorService.execute(() -> {
try {
TimeUnit.SECONDS.sleep(2);
System.out.println("执行第二个操作");
} catch (InterruptedException e) {
} finally {
latch.countDown();
}
});
executorService.execute(() -> {
try {
TimeUnit.SECONDS.sleep(3);
System.out.println("执行第三个操作");
} catch (InterruptedException e) {
} finally {
latch.countDown();
}
});
// 等待前三个执行完毕
latch.await();
System.out.println("执行第四个操作");
executorService.shutdown();
}
三个异步方法返回 CompletableFuture
使用CompletableFuture.allOf 等待三个异步方法都执行完毕
再调用第4个方法
可以在异步任务完成后写一个状态,这个状态可以写到像Redis这样的内存数据库中。
由最后的Utils.selectAll()检测完成状态后继续执行。
1验证+阻塞 2自旋查询有结果就返回 3利用CountDownLatch 你要的不是顺序执行 要的是前置条件先完成
直接用注解好像不行,写了个demo
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Utils.class, ExecutorConfiguration.class})
public class Test {
@Autowired
Utils utils;
@org.junit.Test
public void test1() {
final Future<?> future = utils.insertUser();
final Future<?> future1 = utils.insertAddress();
final Future<?> future2 = utils.insertInformation();
while (true) {
if (future.isDone() && future1.isDone() && future2.isDone()) {
utils.selectAll();
break;
}
}
}
}
@TestComponent
class Utils {
@Autowired
ThreadPoolTaskExecutor executor;
public static void selectAll() {
System.out.println("=====selectAll===");
}
public Future<?> insertUser() {
final Future<?> insertUser = executor.submit(() -> {
System.out.println("======insertUser======");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
return insertUser;
}
public Future<?> insertAddress() {
final Future<?> insertUser = executor.submit(() -> {
System.out.println("======insertAddress======");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
return insertUser;
}
public Future<?> insertInformation() {
final Future<?> insertUser = executor.submit(() -> {
System.out.println("======insertInformation======");
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
return insertUser;
}
}
@TestConfiguration
@EnableAsync
class ExecutorConfiguration {
@Bean
public ThreadPoolTaskExecutor asyncZipPictureThreadPool() {
ThreadPoolTaskExecutor pool = new ThreadPoolTaskExecutor();
pool.setCorePoolSize(10);
return pool;
}
}
您好,我是有问必答小助手,你的问题已经有小伙伴为您解答了问题,您看下是否解决了您的问题,可以追评进行沟通哦~
如果有您比较满意的答案 / 帮您提供解决思路的答案,可以点击【采纳】按钮,给回答的小伙伴一些鼓励哦~~
ps:问答VIP仅需29元,即可享受5次/月 有问必答服务,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632