java异步处理方式
1.Future 和 Callable 接口
基本原理
Future接口用于表示一个异步计算的结果。它提供了一些方法来检查计算是否完成、获取计算结果等。Callable接口类似于Runnable,但是它可以返回一个结果并且可以抛出异常。可以通过ExecutorService来提交一个Callable任务,返回一个Future对象。
例如,计算一个整数的平方并异步返回结果:
import java.util.concurrent.*;
public class FutureExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Integer> callable = () -> {
// 模拟耗时计算
Thread.sleep(2000);
return 5 * 5;
};
Future<Integer> future = executor.submit(callable);
try {
// 这里会阻塞,直到任务完成
System.out.println("计算结果: " + future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
} finally {
executor.shutdown();
}
}
}
局限性
Future的get方法在获取结果时会阻塞当前线程,如果任务没有完成,线程就会一直等待。另外,它不能方便地组合多个异步任务进行链式调用或并行执行等复杂操作。
CompletableFuture(Java 8+)
基本原理
CompletableFuture是 Java 8 引入的一个强大的异步编程工具。它实现了Future和CompletionStage接口,可以方便地进行异步任务的组合、链式调用、并行执行等操作。
例如,两个异步任务,一个计算数字的平方,另一个计算数字的立方,然后将结果相加:
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
// 模拟耗时计算
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 5 * 5;
});
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 5 * 5 * 5;
});
CompletableFuture<Integer> combinedFuture = future1.thenCombine(future2, (result1, result2) -> result1 + result2);
try {
System.out.println("组合任务结果: " + combinedFuture.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
功能特点
链式调用:可以使用thenApply、thenAccept等方法进行链式操作。例如,thenApply可以对异步任务的结果进行进一步的转换计算。
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> 5)
.thenApply(result -> result * 2);
try {
System.out.println("链式计算结果: " + future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
异常处理:可以使用exceptionally方法来处理异步任务中出现的异常。例如:
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
throw new RuntimeException("模拟异常");
}).exceptionally(ex -> {
System.out.println("捕获异常: " + ex.getMessage());
return -1;
});
try {
System.out.println("异常处理后的结果: " + future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
并行执行和组合多个任务:除了前面提到的thenCombine,还可以使用allOf和anyOf。allOf用于等待所有给定的CompletableFuture任务完成,anyOf用于在给定的任务中有一个完成时就返回。
CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);
CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(future1, future2);
基于线程池和 Runnable 接口(较简单的异步方式)
基本原理
可以创建一个线程池,然后将实现了Runnable接口的任务提交到线程池中执行。Runnable接口只有一个run方法,用于定义任务的逻辑。
例如,简单地打印一个消息的异步任务:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolRunnableExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
Runnable task = () -> {
System.out.println("异步任务执行");
};
executor.submit(task);
executor.shutdown();
}
}
局限性
这种方式的局限性在于Runnable接口不能返回结果。如果需要获取任务的结果,就需要使用其他机制,如共享变量等,这样会增加代码的复杂性和出错的可能性。并且在处理复杂的异步任务组合时,没有CompletableFuture那么方便。
🏰 大屏可视化 带你体验酷炫大屏
💯 神秘个人简介 带你体验不一样得介绍
💘 为爱表白 为你那个TA,体验别致的浪漫惊喜
🎀 酷炫邀请函 带你体验高大上得邀请
亲,码字不易,动动小手,欢迎 点赞 ➕ 收藏,如 🈶 问题请 留言(私信或评论),博主看见后一定及时给您答复,💌💌💌
- 点赞
- 收藏
- 关注作者
评论(0)