我们如何将可调用对象转换为可运行对象
How can we convert a callable into a runnable
我有一个 class 实现了可调用接口。我想使用 ScheduledExecutorService 接口的 scheduleAtFixedRate 方法为 class 安排任务。然而,scheduleAtFixedRate 需要一个可运行的对象作为它可以调度的命令。
因此我需要一些方法来将可调用对象转换为可运行对象。我尝试了简单的转换,但它不起作用。
示例代码:
package org.study.threading.executorDemo;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
class ScheduledExecutionTest implements Callable<String> {
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
System.out.println("inside the call method");
return null;
}
}
public class ScheduledExecution {
public static void main(String[] args) {
ScheduledExecutorService sec = Executors.newScheduledThreadPool(10);
sec.scheduleAtFixedRate(new ScheduledExecutionTest(), 5, 2, TimeUnit.SECONDS);
}
}
为什么不使用类似的东西:
final Callable<YourType> callable = ...; // Initialize Callable
Runnable callableAsRunnable = () -> {
try {
callable.call();
} catch (Exception e) {
// Handle the exception locally or throw a RuntimeException
}
};
假设您真的不需要 Callable
到 return 任何有用的东西,您可以将 Callable 包装为 Runnable
Runnable run = new Runnable() {
public void run() {
try {
Object o = callable.call();
System.out.println("Returned " + o);
} catch (Exception e) {
e.printStackTrace();
}
}
};
或在Java 8
Runnable run = () -> {
try {
Object o = callable.call();
System.out.println("Returned " + o);
} catch (Exception e) {
e.printStackTrace();
}
};
这很混乱,但听起来 Callable 应该首先是一个 Runnable,您不必这样做。
使用future task,它实现了Runnable和callable,你不需要改变你的代码。
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/FutureTask.html
FutureTask task1 = new FutureTask(Callable<V> callable)
现在这个任务 1 可以运行了,因为:
class FutureTask<V> implements RunnableFuture<V>
RunnableFuture<V> extends Runnable, Future<V>
所以从上面两个关系来看,task1是可运行的,可以在Executor.execute(Runnable)
方法中使用
JDK 有一个 util 方法就是为了这个:
Runnable runnable = ..
Executors.callable(runnable);
我有一个 class 实现了可调用接口。我想使用 ScheduledExecutorService 接口的 scheduleAtFixedRate 方法为 class 安排任务。然而,scheduleAtFixedRate 需要一个可运行的对象作为它可以调度的命令。
因此我需要一些方法来将可调用对象转换为可运行对象。我尝试了简单的转换,但它不起作用。
示例代码:
package org.study.threading.executorDemo;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
class ScheduledExecutionTest implements Callable<String> {
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
System.out.println("inside the call method");
return null;
}
}
public class ScheduledExecution {
public static void main(String[] args) {
ScheduledExecutorService sec = Executors.newScheduledThreadPool(10);
sec.scheduleAtFixedRate(new ScheduledExecutionTest(), 5, 2, TimeUnit.SECONDS);
}
}
为什么不使用类似的东西:
final Callable<YourType> callable = ...; // Initialize Callable
Runnable callableAsRunnable = () -> {
try {
callable.call();
} catch (Exception e) {
// Handle the exception locally or throw a RuntimeException
}
};
假设您真的不需要 Callable
到 return 任何有用的东西,您可以将 Callable 包装为 Runnable
Runnable run = new Runnable() {
public void run() {
try {
Object o = callable.call();
System.out.println("Returned " + o);
} catch (Exception e) {
e.printStackTrace();
}
}
};
或在Java 8
Runnable run = () -> {
try {
Object o = callable.call();
System.out.println("Returned " + o);
} catch (Exception e) {
e.printStackTrace();
}
};
这很混乱,但听起来 Callable 应该首先是一个 Runnable,您不必这样做。
使用future task,它实现了Runnable和callable,你不需要改变你的代码。
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/FutureTask.html
FutureTask task1 = new FutureTask(Callable<V> callable)
现在这个任务 1 可以运行了,因为:
class FutureTask<V> implements RunnableFuture<V>
RunnableFuture<V> extends Runnable, Future<V>
所以从上面两个关系来看,task1是可运行的,可以在Executor.execute(Runnable)
方法中使用
JDK 有一个 util 方法就是为了这个:
Runnable runnable = ..
Executors.callable(runnable);