3

У меня есть класс, который реализует вызываемый интерфейс. Я хочу запланировать задачу для класса, используя метод scheduleAtFixedRate интерфейса ScheduledExecutorService. Однако schedAtFixedRate требует запускаемого объекта в качестве команды, которую он может планировать.Как мы можем преобразовать вызываемый в runnable

Следовательно, мне нужен способ, которым я могу преобразовать вызываемый в runnable. Я пробовал простое кастинг, но это не работает.

ОБРАЗЦА КОД:

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

ответ

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

Сейчас этот task1 является работоспособным, потому что:

  1. class FutureTask<V> implements RunnableFuture<V>
  2. RunnableFuture<V> extends Runnable, Future<V>

Так свыше двух отношений, task1 является работоспособным и может использоваться внутри Executor.execute(Runnable) метод

+0

Хотя FutureTask - удобный способ получения Runnable из Callable, обратите внимание, что JavaDoc for FutureTask указывает, что вычисление не может быть перезапущено после завершения, что означает, что он действителен только один раз. Учитывая, что вопрос заключается в предоставлении Runnable для scheduleAtFixedRate, который пытается выполнить несколько раз, FutureTask не подходит для этой цели, хотя он может быть полезен в других случаях, когда требуется только одно выполнение. Ссылка JavaDoc: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/FutureTask.html – njr

0

Почему бы не использовать что-то вроде:

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

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

Предполагая, что вы на самом деле не нужен Callable вернуть что-нибудь полезное, вы можете обернуть Callable как Runnable

или в Java 8

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

Это довольно грязно, но похоже, что Callable должно было быть Runnable в первую очередь, и вам не нужно было это делать.