Java多线程可以实现异步执行任务,提高程序运行效率和响应速度。在多线程执行完成后,需要获取线程执行结果,而Callable与FutureTask就是实现多线程返回值的一种方式。下面就是Java多线程返回值的使用示例(callable与futuretask)。
Callable 接口
Callable接口是一个泛型接口,它声明了call()方法,可以有返回值,也可以抛出异常。Callable与Runnable接口有点类似,都是用来定义线程执行的任务。但Runnable没有返回值,Callable有返回值。下面是Callable接口示例。
import java.util.concurrent.Callable;
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
return sum;
}
}
在这个示例中,MyCallable实现了Callable接口,重写了call()方法,计算0到99的和,并返回结果。
FutureTask 类
FutureTask类是Future接口的一个实现类,它实现了除了get()和cancel()方法以外的Future接口方法。同时,FutureTask也可以用来计算Callable任务。
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class FutureTaskDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
Callable<Integer> myCallable = new MyCallable();
FutureTask<Integer> futureTask = new FutureTask<>(myCallable);
new Thread(futureTask).start();
System.out.println("计算结果:" + futureTask.get());
}
}
在这个示例中,我们创建了一个MyCallable对象,将它传递给FutureTask构造函数,再启动一个线程执行FutureTask,并使用get()方法获取执行结果。
示例一
接下来,我们来看一个更加实际的例子。假设我们有一个计算税额的任务需要运行,但这个任务给定的参数可能很大。如果不使用多线程,就需要等待很久才能获取结果。而使用多线程后,可以通过Callable和FutureTask实现异步计算,提高程序响应速度。
import java.util.concurrent.Callable;
public class CalculateTax implements Callable<Double> {
private double income; // 收入
public CalculateTax(double income) {
this.income = income;
}
@Override
public Double call() throws Exception {
// 计算税额
double tax;
if (income <= 10000) {
tax = income * 0.1;
} else {
tax = income * 0.2;
}
Thread.sleep(3000); // 模拟计算时间
return tax;
}
}
在这个示例中,我们创建了一个CalculateTax对象,它实现了Callable接口,重写了call()方法,计算税额并返回结果。因为计算税额可能需要较长时间,我们在返回结果前sleep了3秒钟,模拟计算过程。
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Test {
public static void main(String[] args) throws ExecutionException, InterruptedException {
double income = 20000; // 收入
CalculateTax calculateTax = new CalculateTax(income);
FutureTask<Double> futureTask = new FutureTask<>(calculateTax);
new Thread(futureTask).start();
System.out.println("正在计算税额...");
double tax = futureTask.get(); // 获取计算结果
System.out.println("税额为:" + tax);
}
}
在这个示例中,我们启动一个线程执行CalculateTax任务,并使用FutureTask获取计算结果。由于计算过程可能较长,我们在调用get()方法时阻塞当前线程,等待计算完成。程序运行结果如下:
正在计算税额...
税额为:4000.0
可以看到,我们通过异步计算的方式,成功地获取了税额,即使计算过程较长,程序也能够快速进行响应。
示例二
接下来,我们再来看一个示例,演示如何同时执行多个Callable任务,并获取它们的结果。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class MultipleCallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
int nThreads = Runtime.getRuntime().availableProcessors();
ExecutorService executorService = Executors.newFixedThreadPool(nThreads); // 创建一个线程池
List<Callable<Integer>> listOfCallables = new ArrayList<>(); // 创建一个Callable任务列表
for (int i = 0; i < nThreads; i++) {
listOfCallables.add(new MyCallable()); // 将多个Callable任务加入列表
}
List<Future<Integer>> futures = executorService.invokeAll(listOfCallables); // 执行多个Callable任务
for (Future<Integer> future : futures) {
System.out.println(future.get()); // 输出结果
}
executorService.shutdown(); // 关闭线程池
}
}
在这个示例中,我们创建了一个ExecutorService线程池,用来执行多个Callable任务。通过for循环,将多个MyCallable对象加入到Callable任务列表中,然后通过invokeAll()方法执行这些任务。最后使用for循环遍历获取多个线程执行结果,并输出。程序运行结果如下所示:
4950
4950
4950
4950
可以看到,我们通过ExecutorService线程池来执行多个MyCallable任务,并获取它们的结果。这样的方式可以进一步提高程序的运行效率。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java多线程返回值使用示例(callable与futuretask) - Python技术站