实现:通过 CompletableFuture + ThreadPoolExecutor : 异步编辑器 + 自定义线程池实现异步批量插入
场景:模拟批量向数据库中插入 User 信息。
主要对象:User(id, name)
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 利用 CompletableFutrue + ThreadPoolExecutor 实现异步批量处理数据
*
* 注:控制台数据很耗时。建议只输出线程名
*/
public class CompletableFutrue {
public static void main(String[] args) {
// 1.创建异步 list 集合与自定义线程池
List<CompletableFuture<Void>> futures = new ArrayList<>();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
20, 50, 10000, TimeUnit.MILLISECONDS,
new ArrayBlockingQueue<>(10000));
int saveBatch = 5000;
int count = 1;
// 模拟方法在逻辑层应该是:userService
Person temPerson = new Person();
long start = System.currentTimeMillis();
// 20 批次
for (int i = 0; i < 20; i++) {
ArrayList<Person> persons = new ArrayList<>();
// 每批次
while (true) {
Person person = new Person();
person.setId(count++);
person.setName("name");
persons.add(person);
// 达到批次弹出
if (count % saveBatch == 0) {
break;
}
}
// 2.异步执行,构建批次执行对象
CompletableFuture<Void> future = CompletableFuture.runAsync(()->{
System.out.println("进入批次处理:" + Thread.currentThread().getName());
temPerson.aaa(persons);
}, executor);
// 添加到线程集合
futures.add(future);
}
// 3.将futures集合中的元素转为串行化执行
CompletableFuture.allOf(futures.toArray(new CompletableFuture[]{})).join();
long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "ms");
}
}
class Person {
private int id;
private String name;
public void aaa(List<Person> list) {
// 假设;userService.saveBatch()
Collections.reverse(list);
}
// 构造方法
public Person() {
}
public Person(int id, String name) {
this.id = id;
this.name = name;
}
// setter getter
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Person( " +
"id=" + this.id +
", name=" + this.name +
")";
}
}