2016-11-04 5 views
1

Я хочу отправить некоторых SwingWorkers в ExecutorService и получить от них фьючерсы, чтобы увидеть их позже, если они закончили и какие результаты.Получение будущего с правильным типом из ExecutorService с использованием SwingWorker runnables

Однако метод отправки ExecutorService возвращает только Future<?>, когда я хочу Future<Integer>.

Итак, вопросы:

  • Правильно ли я простирающийся SwingWorker? Первый общий тип - это то, что возвращается get() в SwingWorker, поэтому я догадался, что это также будет возвращено методом get get().

  • Неправильно ли использовать SwingWorker? (Пытаясь прочитать об этой проблеме, я вижу, что в основном люди передают Callables в ExecutorService). Если да, то что было бы лучше и каков наилучший способ ее преобразования? (мое фактическое расширение SwingWorker более сложное, чем этот пример, и обновляет графический интерфейс и т. д.). Я начал пытаться реализовать Callable в новом классе, но я не уверен, как реализовать процесс публикации/процесса (каламбур не предназначен).

Некоторые пример кода, который воспроизводит проблему:

Расширение SwingWorker

import javax.swing.SwingWorker; 

public class Worker extends SwingWorker<Integer, Void> 
{ 
    public Worker() 
    { 

    } 

    @Override 
    public Integer doInBackground() 
    { 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return 1; 
    } 

    @Override 
    public void done() 
    { 
     System.out.println("done\n"); 
    } 
} 

Главная - executor.submit(w) часть дает ошибку компиляции:

Type mismatch: cannot convert from Future<capture#1-of ?> to Future<Integer> 

И спрашивает, если я Я хотел бы изменить будущее на тип Future<?> или нарисовать executor.submit(w) часть до Future<Integer>.

import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 

public class Main 
{ 
    public static void main (String[] args) 
    { 
     ExecutorService executor = Executors.newFixedThreadPool(2); 

     Worker w = new Worker(); 
     Future<Integer> future = executor.submit(w); 
    } 
} 

ответ

2

Вы можете использовать этот вариант submit() сделать тип результата Явный:

<T> Future<T> submit(Runnable task, T result) 

Как обсуждалось here, submit() ничего не делать с result. «Когда задача будет успешно завершена, вызов future.get() вернет результат, в который вы прошли». Обратите внимание, что тип result соответствует типу результата SwingWorker, T.

Код:

Integer i = 42; 
Future<Integer> future = executor.submit(w, i); 
System.out.println(future.get()); 

консоли:

42 
done 

В более широком контексте вашей фактической программы, вы хотите publish() промежуточных результатов и process() их на EDT.

+0

Означает ли это, что невозможно получить результат doInBackground() SwingWorker? – Quantumcat

+0

Нет, вы можете использовать 'get()' пользователя. – trashgod

+0

Спасибо, я не понимал, что у SwingWorker есть будущее. Итак, теперь я собираюсь сделать executor.execute (w) и поместить все w на карту, чтобы посмотреть на них позже. Если кому-то интересно, как работает SwingWorker, я нашел исходный код здесь http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/javax/swing/SwingWorker.java # SwingWorker – Quantumcat