Статьи

Как использовать Callable и FutureTask

Вступление

Начиная с Java 1.5 в java.util.concurrent появился новый набор объектов. Этот пакет имеет несколько различных классов, включая очереди потоков. Я мог бы использовать их, когда программировал на Java 1.2! Когда я начал смотреть на новые игрушки, я стал колебаться. Что это за вызываемая вещь и каково будущее? Оказывается, в Future и Callable нет ничего плохого. На самом деле, это то, на что я надеялся в своей карьере Java.

Различия между Callable и Runnable

Callable — это то, на что надеялся Runnable. Единственный метод Callable — это «T call ()». Что делает его таким аккуратным, так это то, что он что-то возвращает. Это шаг над созданием геттера для ответа на задачу. Хотя это круто, должен быть способ получить возвращаемое значение.

Будущее здесь

Будущее способ вывести ценность, когда Callable будет сделано. Функция get () или get (длинный тайм-аут, единица времени). Это эквивалентно вызову thread.join (); runnable.getValue () одновременно.

пример

Я создал класс с именем CounterCallable. Все, что он делает, это добавляет числа от начала переменной до конца переменной.

CounterCallable

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package org.mathison.futurecallable;
 
import java.util.concurrent.Callable;
 
/**
 *
 * @author Daryl
 */
public class CounterCallable implements Callable {
 
    private long start;
    private long end;
 
    public CounterCallable(long start, long end) {
        this.start = start;
        this.end = end;
    }
 
    @Override
    public SumTimeAnswer call() throws Exception {
        long sum = 0;
        long startTime = System.currentTimeMillis();
        for(long i = start; i <= end; i++){
            sum += i;
        }
        long endTime = System.currentTimeMillis();
 
        return new SumTimeAnswer(sum, endTime - startTime);
    }
}

SumTimeAnswer

Класс SumTimeAnswer — это действительно простой класс-получатель, который содержит сумму и время, затраченное на выполнение операции.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package org.mathison.futurecallable;
 
/**
 *
 * @author Daryl
 */
public class SumTimeAnswer {
    private long timeToFinish;
    private long sum;
 
    public SumTimeAnswer(long sum, long timeToFinish) {
        this.sum = sum;
        this.timeToFinish = timeToFinish;
    }
 
    public long getTimeToFinish() {
        return timeToFinish;
    }
 
    public long getSum() {
        return sum;
    }
}

Приложение

Приложение — это просто основной класс, объединяющий все

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package org.mathison.futurecallable;
 
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
 
/**
 * Hello world!
 *
 */
public class App
{
    public static final long BEGIN = 0;
    public static final long END = 100000;
    public static void main( String[] args )
    {
        FutureTask task = new FutureTask(new CounterCallable(BEGIN, END));
        FutureTask firstHalf = new FutureTask(new CounterCallable(BEGIN, END/2));
        FutureTask secondHalf = new FutureTask(new CounterCallable(END/2 + 1, END));
         
        ExecutorService pool = Executors.newSingleThreadExecutor();
        pool.submit(task);
        pool.submit(firstHalf);
        pool.submit(secondHalf);
         
        try {
            SumTimeAnswer taskAnswer = task.get();
            System.out.println("just one thread Time: " + taskAnswer.getTimeToFinish()
                + " Total: " + taskAnswer.getSum());
             
             
            SumTimeAnswer taskFirstAnswer = firstHalf.get();
            SumTimeAnswer taskSecondAnswer = secondHalf.get();
            long totalTime = taskFirstAnswer.getTimeToFinish() + taskSecondAnswer.getTimeToFinish();
            long totalSum = taskFirstAnswer.getSum() + taskSecondAnswer.getSum();
            System.out.println("Two thread time: " + totalTime + " Total: " + totalSum);
        } catch(CancellationException | InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        pool.shutdown();
    }
}

Вывод

В этом посте классы Callable и FutureTask были использованы для демонстрации использования пакета java.util.concurrent.