系列文章目录
文章目录
- 系列文章目录
- 前言
前言
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章男女通用,看懂了就去分享给你的码吧。
常见的两种创建线程的方式。一种是直接继承Thread,另外一种就是实现Runnable接口。
这两种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。
从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。
Future模式的核心思想是能够让主线程将原来需要同步等待的这段时间用来做其他的事情。(因为可以异步获得执行结果,所以不用一直同步等待去获得执行结果)。
这里给一个实际使用的案例代码,理论是一样的,但是编码方式有多种。
关于代码的注意点和说明,都在注释里面,由于案例比较简单,这里不再啰嗦。
package com.example.springboot;
import com.alibaba.fastjson2.JSON;
import com.example.springboot.entity.User;
import com.example.springboot.mapper.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.function.Supplier;
/*** Future 机制测试*/
@SpringBootTest
public class FutureTest {@Autowiredprivate UserMapper userMapper;private static ThreadPoolExecutor pool;static {pool = (ThreadPoolExecutor) Executors.newFixedThreadPool(10);}@Testpublic void test1() throws Exception {// 创建一个调用次数为2的计数工具CountDownLatch countDownLatch = new CountDownLatch(2);// 直接在异步内组装返回数据,注意List不是线程安全的,也可以采用Vector或者synchronized关键字方式List<User> listTmp = new CopyOnWriteArrayList<>();// 通过异步返回接收,因为是编码依次接收,所以不存在安全问题List<User> listRe = new ArrayList<>();// 异步执行 1CompletableFuture<User> reStrFu1 = CompletableFuture.supplyAsync(new Supplier<User>() {@Overridepublic User get() {try {Thread.sleep(2000);// 获取结果方式1,直接组装到上层方法变量中User user = userMapper.selectById(1);listTmp.add(user);return user;}catch (Exception e){e.printStackTrace();}finally {countDownLatch.countDown(); // 异步执行结束}return null;}}, pool);// 异步执行 2CompletableFuture<User> reStrFu2 = CompletableFuture.supplyAsync(new Supplier<User>() {@Overridepublic User get() {try {Thread.sleep(2000);// 获取结果方式1,直接组装到上层方法变量中User user = userMapper.selectById(2);listTmp.add(user);return user;}catch (Exception e){e.printStackTrace();}finally {countDownLatch.countDown(); // 异步执行结束}return null;}}, pool);// // 获取结果方式2,带超时的参数
// listRe.add(reStrFu1.get(10, TimeUnit.SECONDS)); // 可以定义获取超时时间
// listRe.add(reStrFu2.get(10, TimeUnit.SECONDS)); // 可以定义获取超时时间// 获取结果方式3,等待计数结束try {countDownLatch.await();} catch (Exception e) {e.printStackTrace();}listRe.add(reStrFu1.get());listRe.add(reStrFu2.get());System.out.println("listTmp" + JSON.toJSONString(listTmp));System.out.println("listRe" + JSON.toJSONString(listRe));}
}
最后打印结果是一样的,都是两条数据的JSON。