我们如何将可调用对象转换为可运行对象

问题描述:

我有一个实现了可调用接口的类。我想使用ScheduledExecutorService接口的scheduleAtFixedRate方法为该类安排任务。然而,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); 
    } 
} 
+0

'实现Callable,Runnable'不行吗?我从来没有尝试过使用两种。 – Zircon

+0

Callable的目的是返回一个值。为什么你会返回一个你想放弃的价值固定的价格? –

+2

把@ PeterLawrey的评论换个角度来看,你想用'Callable'返回的值做什么? – dcsohl

FutureTask task1 = new FutureTask(Callable<V> callable) 

现在这个任务1是可运行的,因为:

  1. class FutureTask<V> implements RunnableFuture<V>
  2. RunnableFuture<V> extends Runnable, Future<V>
从上面两个关系

所以,TASK1可运行,并可以在里面使用Executor.execute(Runnable)方法

+0

虽然FutureTask是从Callable获取Runnable的一种便捷方式,但请注意,JavaDoc for FutureTask指定计算一旦完成就无法重新启动,这意味着它只能运行一次。假设问题是提供一个Runnable到scheduleAtFixedRate,它试图多次运行,FutureTask并不适合这个目的,尽管在其他情况下只需要一次执行就可以使用。 JavaDoc链接: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/FutureTask.html – njr

为什么不使用这样的:

final Callable<YourType> callable = ...; // Initialize Callable 

    Runnable callableAsRunnable =() -> { 
    try { 
     callable.call(); 
    } catch (Exception e) { 
     // Handle the exception locally or throw a RuntimeException 
    } 
    }; 

假设你并不真的需要Callable返回有用的东西,你可以用一个Callable作为一个Runnable

Runnable run = new Runnable() { 
    public void run() { 
     try { 
      Object o = callable.call(); 
      System.out.println("Returned " + o); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
}; 

or in Java 8

Runnable run =() -> { 
    try { 
     Object o = callable.call(); 
     System.out.println("Returned " + o); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
}; 

这很麻烦,但它听起来像Callable本来应该是一个Runnable,你不必这样做。

使用未来的任务,它实现了Runnable和callable,你不需要更改你的代码。

https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/FutureTask.html