Java多线程之FutureTask的介绍及使用
介绍
FutureTask
是Java提供的一种异步计算结果的方式。它可以在一个线程中执行异步的计算,同时能够在另一个线程中获取计算结果。FutureTask
实现了Future
接口和Runnable
接口,因此它可以被当做一个任务提交给ThreadPoolExecutor
等线程池来执行。
使用
创建FutureTask对象
FutureTask
的构造函数接受一个Callable类型的参数,表示计算任务。创建一个FutureTask
对象通常的方式是通过一个实现了Callable
接口的类,然后在FutureTask
的构造函数中传入这个实现类的实例:
FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
// 计算任务
return 1 + 1;
}
});
执行FutureTask任务
FutureTask
对象有两种方式执行任务:
- 手动执行:通过调用
FutureTask
对象的run()
方法可以手动执行任务,但是这是在当前线程中执行任务,不会体现出FutureTask
的异步特性。 - 提交到线程池:通过将
FutureTask
对象提交到线程池中去执行,即可体现出FutureTask
的多线程异步特性。
以下是手动执行的示例代码:
futureTask.run();
int result = futureTask.get();// 该方法会阻塞当前线程,直到获取到结果
下面是提交到线程池的示例代码:
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(futureTask);
int result = futureTask.get();// 该方法会阻塞当前线程,直到获取到结果
executorService.shutdown();
获取FutureTask任务结果
FutureTask
对象的get()
方法会阻塞当前线程,直到获取到计算结果或者抛出异常,如果在调用get()
方法的时候任务还没有执行完成,那么get()
方法会一直阻塞。
以下是获取计算结果的示例代码:
int result = futureTask.get();
判断FutureTask任务是否完成
FutureTask
对象有一个isDone()
方法,用来判断计算任务是否已经完成,返回一个布尔值。
以下是判断FutureTask
任务是否完成的示例代码:
boolean isDone = futureTask.isDone();
if (isDone) {
int result = futureTask.get();
}
取消FutureTask任务
FutureTask
对象可以通过cancel()
方法来取消任务的执行。如果任务已经执行完成或者已经被取消了,那么这个方法将会返回false。如果任务正在执行或者还没有被执行,那么这个方法将会尝试将任务取消,并返回true。
以下是取消FutureTask
任务的示例代码:
boolean isCancelled = futureTask.cancel(true);// 参数表示是否中断正在执行的任务
示例
示例1
下面是一个简单的示例,展示如何使用FutureTask
来计算一个数的平方值:
FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return 2 * 2;
}
});
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(futureTask);
int result = futureTask.get();
System.out.println(result);// 输出:4
executorService.shutdown();
示例2
下面是一个更加复杂的示例,展示如何使用FutureTask
来实现异步请求,请求百度搜索结果的数量:
FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
URL url = new URL("https://www.baidu.com/s?wd=FutureTask");
URLConnection connection = url.openConnection();
InputStream inputStream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder result = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
String regex = "<span class=\"nums\">([\\d,]+)</span>";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(result.toString());
if (matcher.find()) {
String count = matcher.group(1).replaceAll(",", "");
return Integer.parseInt(count);
}
return 0;
}
});
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService.submit(futureTask);
int result = futureTask.get();
System.out.println(result);// 输出:大概有1480000个
executorService.shutdown();
总结
本文介绍了Java多线程中的FutureTask
的用法,包括创建FutureTask
对象、执行FutureTask
任务、获取FutureTask
任务结果、判断FutureTask
任务是否完成、取消FutureTask
任务等。同时,通过示例代码,展示了FutureTask
的使用场景和实现方法。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程之FutureTask的介绍及使用 - Python技术站