标题:Java多线程Future和Callable类示例分享
什么是Java的Future和Callable类?
在Java多线程编程中,使用Future和Callable类可以方便地处理异步任务,也可以获取异步任务的结果。
Callable是一个函数式接口,它描述的是具有返回值的任务。可以通过实现Callable接口并实现它的call()方法来定义自己的任务,该方法将在调用时返回一个Future对象。Future对象表示异步计算的结果,可以使用get()方法等待计算完成并返回结果。
Future和Callable的基本用法
下面是一个简单的示例代码,说明如何使用Future和Callable类:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class MyCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("Callable is running...");
Thread.sleep(2000);
return 123;
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
MyCallable callable = new MyCallable();
FutureTask<Integer> futureTask = new FutureTask<>(callable);
Thread t = new Thread(futureTask);
t.start();
System.out.println("主线程在执行其他任务");
Thread.sleep(500);
System.out.println("主线程在等待结果");
System.out.println("FutureTask的结果为:" + futureTask.get());
}
}
我们首先定义了一个实现了Callable接口的MyCallable类,该类的call()方法会返回一个整数123。然后,我们创建一个FutureTask对象,将MyCallable对象的实例传递给它。FutureTask类实际上是一个RunnableFuture实现类,它可以被线程执行。
在主线程中,我们首先启动了一个线程来执行该任务,然后在等待任务执行结果之前,主线程可以执行其他任务,不必等待任务执行完毕的结果。当需要任务执行结果时,可以通过futureTask.get()方法来获取结果。如果任务还未完成,futureTask.get()会使当前线程阻塞,等待任务完成后返回结果。如果任务已经完成,get()方法会立即返回结果。
使用Future和Callable类实现带超时时间的任务
有时候我们需要在任务执行一定时间后就停止该任务,比如用户停止了一个无限循环的计算任务。我们可以通过使用Future和ScheduledExecutorService来实现带超时时间的任务。
下面是一个示例代码,它会执行一个计算斐波那契数列的任务,该任务是一个无限循环,但是我们设置了执行时间,如果任务执行时间超过规定时间,则抛出TimeoutException异常。
import java.util.concurrent.*;
public class TimeoutCallable implements Callable<Long> {
@Override
public Long call() throws Exception {
long i = 0;
while (true) {
i++;
if (Thread.currentThread().isInterrupted()) {
System.out.println("Callable被中断了...");
throw new InterruptedException("Callable被中断了...");
}
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
TimeoutCallable timeoutCallable = new TimeoutCallable();
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Long> future = executor.submit(timeoutCallable);
try {
Long result = future.get(3, TimeUnit.SECONDS);
System.out.println("结果是:" + result);
} catch (TimeoutException e) {
System.out.println("超时了...");
future.cancel(true);
}
executor.shutdownNow();
}
}
我们定义了一个实现Callable接口的TimeoutCallable类,该任务将会一直循环,直到被中断。我们使用ExecutorService创建了一个单线程池,并将TimeoutCallable对象交给它执行。
在main()方法中,我们调用future.get(3, TimeUnit.SECONDS)方法等待任务执行结果,但是我们将等待时间设置为3秒钟。如果任务没有在3秒钟内完成,就会抛出TimeoutException异常,我们可以通过该异常处理机制来取消任务执行并停止该任务。
通过这两个示例,我们可以看到Future和Callable类的基本用法和带超时时间执行任务的机制。使用Future和Callable类可以很方便地异步处理任务,也可以优雅地处理任务执行结果和异常。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java多线程Future和Callable类示例分享 - Python技术站