如何实现多线程?
提到实现多线程的实现方式,想必肯定会想到继承Thread
类,实现Runnable
类,然后重写run
方法,但是这两种都不够方便,接下来我将用三种方式实现多线程 推荐第三种使用方式(函数式编程)
注:
严格上讲 第三种不是实现多线程的方式,只是前两种的简化 线程池加上lambda让我们写起多线程来更加便捷
方式一 继承Thread
类
public class ThreadTest extends Thread{
private final int a;
private final int b;
public ThreadTest(int a, int b) {
this.a = a;
this.b = b;
}
@Override
public void run() {
System.out.println(b);
System.out.println(a + b);
}
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 50, 3, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10), new ThreadPoolExecutor.CallerRunsPolicy());
for (int i = 0; i < 10; i++) {
executor.execute(new ThreadTest(i, i + new Random().nextInt(10)));
}
}
}
方式二 实现Runnable
类
public class RunnableTest implements Runnable{
@Override
public void run() {
System.out.println("测试" + Thread.currentThread().getName());
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
Thread thread = new Thread(new RunnableTest());
thread.start();
}
}
}
- 方式一 继承了Threa类 手动创建了线程池执行多线程
- 方式二 实现了Rnuuable类 直接new 了一个新的线程 调用
start
方法
但是这两种很臃肿 看起来就不好理解,尤其当传递参数的时候,就像方式一中 需要创建属性 构造方法进行传参,也不够直观,得益于`jdk8’ 的函数式编程,我们可以将多线程的使用变得简单起来
方式三 使用函数式编程
public class ThreadPoolTest {
public static void main(String[] args) {
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 50, 3, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10), new ThreadPoolExecutor.CallerRunsPolicy());
for (int i = 0; i < 10; i++) {
AtomicInteger num = new AtomicInteger(i);
executor.execute(() -> test(num.get(), num.get() + new Random().nextInt(10)) );
}
}
private static void test(int a, int b) {
int c = a + b;
System.out.println(a + "+" + b + "=" + c);
}
}
这里我们省去了去继承Thread类、实现 Tunnable类,专注于书写需要执行的哪一个方法,也不用再去单独创建构造方法,新建属性,直接通过labda表达式就能轻松实现多线程,这样我们就可以轻松愉快的使用多线程了。
executor.execute 没有返回值
complateFuture变成
public TableDataInfo getInfoAll(@RequestBody List<String> fileUrls) throws InterruptedException {
String uploadPath = RuoYiConfig.getUploadPath();
List<CollectorUploadData> list = Lists.newArrayList();
List<String> fileUrlList = Lists.newArrayList(fileUrls);
List<List<String>> partList = Lists.partition(fileUrlList, 20);
List<CompletableFuture<List<CollectorUploadData>>> futures = partList.stream()
.map(dataList -> CompletableFuture.supplyAsync(() -> partData(dataList, uploadPath))).collect(Collectors.toList());
futures.forEach(task -> list.addAll(task.join()));
return getDataTable(list);
}
public List<CollectorUploadData> partData(List<String> fileUrls, String uploadPath) {
List<CollectorUploadData> list = Lists.newArrayList();
fileUrls.forEach(fileUrl -> {
fileUrl = uploadPath + fileUrl.substring(15);
List<CollectorUploadData> fileData = getFileData(fileUrl);
if(CollUtil.isNotEmpty(fileData)) {
list.addAll(fileData);
}
});
return list;
}