Heim  >  Artikel  >  Java  >  Java-Concurrency-Callable, Future und FutureTask

Java-Concurrency-Callable, Future und FutureTask

黄舟
黄舟Original
2017-01-19 11:56:261465Durchsuche

Es gibt zwei Möglichkeiten, einen Thread zu erstellen: Eine besteht darin, Thread direkt zu erben, und die andere darin, die Runnable-Schnittstelle zu implementieren

Unterschied: Die Schnittstelle kann Mehrfachvererbung implementieren

Der Fehler ist: nach der Ausführung der Aufgabe Die Ausführungsergebnisse können danach nicht abgerufen werden

Callable and Runnable

java.lang.Runnable

[code]public interface Runnable {
    public abstract void run();
}

Da der Rückgabewert des Laufs( )-Methode vom Typ „void“ ist, wird die Aufgabe nicht ausgeführt, nachdem keine Ergebnisse zurückgegeben werden können.

java.util.concurren

[code]public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

Generische Schnittstelle, der von der Funktion call() zurückgegebene Typ ist der übergebene V-Typ

Im Allgemeinen wird er in verwendet Verbindung mit ExecutorService Verwendet werden mehrere überladene Versionen der Submit-Methode in der ExecutorService-Schnittstelle deklariert

[code]<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);

Future

Future dient dazu, die Ausführungsergebnisse bestimmter ausführbarer oder aufrufbarer Aufgaben abzubrechen und abzufragen. Abschließen, Ergebnisse erhalten. Bei Bedarf können Sie das Ausführungsergebnis über die get-Methode abrufen. Diese Methode blockiert, bis die Aufgabe das Ergebnis zurückgibt. Die Abbruchmethode wird verwendet, um die Aufgabe abzubrechen , gibt es „true“ zurück. Wenn der Aufgabenabbruch fehlschlägt, wird „false“ zurückgegeben. Der Parameter mayInterruptIfRunning gibt an, ob ausgeführte, aber noch nicht abgeschlossene Aufgaben abgebrochen werden dürfen. Wenn er auf true gesetzt ist, bedeutet dies, dass laufende Aufgaben abgebrochen werden können. Wenn die Aufgabe abgeschlossen wurde, unabhängig davon, ob mayInterruptIfRunning wahr oder falsch ist, gibt diese Methode definitiv false zurück. Das heißt, wenn die abgeschlossene Aufgabe abgebrochen wird, gibt sie false zurück, wenn die Aufgabe ausgeführt wird, wenn mayInterruptIfRunning auf true gesetzt ist. Es wird „true“ zurückgegeben. Wenn „mayInterruptIfRunning“ auf „false“ gesetzt ist, wird „false“ zurückgegeben. Wenn die Aufgabe nicht ausgeführt wurde, wird „mayInterruptIfRunning“ auf jeden Fall „true“ zurückgegeben.

[code]public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}
Die Methode isCancelled gibt an, ob die Aufgabe erfolgreich abgebrochen wurde, bevor die Aufgabe normal abgeschlossen wurde.


Die Methode isDone gibt an, ob die Aufgabe abgeschlossen ist.

Die Methode get() wird verwendet, um das Ausführungsergebnis zu erhalten wartet, bis die Aufgabe abgeschlossen ist, bevor sie zurückgegeben wird.

get(long timeout, TimeUnit unit) wird verwendet, um das Ausführungsergebnis zu erhalten. Wenn das Ergebnis nicht innerhalb der angegebenen Zeit erhalten wird, wird null zurückgegeben.

Das heißt, Future bietet drei Funktionen:

1) Bestimmen, ob die Aufgabe abgeschlossen ist

2) Kann die Aufgabe unterbrechen; > 3) Kann Ergebnisse der Aufgabenausführung abrufen.

Da Future nur eine Schnittstelle ist, kann es nicht direkt zum Erstellen von Objekten verwendet werden. Daher gibt es die folgende FutureTask.

FutureTask


Tatsächlich ist FutureTask die einzige Implementierungsklasse der Future-Schnittstelle.

[code]public class FutureTask<V> implements RunnableFuture<V>
Beispiel
[code]public interface RunnableFuture<V> extends Runnable, Future<V> {
    void run();
}
[code]public FutureTask(Callable<V> callable) {
}
public FutureTask(Runnable runnable, V result) {
}

Wenn Sie Future für die Stornierbarkeit verwenden, aber keine brauchbaren Ergebnisse liefern, können Sie Future deklarieren

[code]public class Test {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newCachedThreadPool();
        Task task = new Task();
        Future<Integer> result = executor.submit(task);
        executor.shutdown();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        System.out.println("主线程在执行任务");

        try {
            System.out.println("task运行结果"+result.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        System.out.println("所有任务执行完毕");
    }
}
class Task implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        System.out.println("子线程在进行计算");
        Thread.sleep(3000);
        int sum = 0;
        for(int i=0;i<100;i++)
            sum += i;
        return sum;
    }
}
Das ist Java-Parallelität -Callable-, Future- und FutureTask-Inhalte. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn)!
[code]public class Test {
    public static void main(String[] args) {
        //第一种方式
        ExecutorService executor = Executors.newCachedThreadPool();
        Task task = new Task();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
        executor.submit(futureTask);
        executor.shutdown();

        //第二种方式,注意这种方式和第一种方式效果是类似的,只不过一个使用的是ExecutorService,一个使用的是Thread
        /*Task task = new Task();
        FutureTask<Integer> futureTask = new FutureTask<Integer>(task);
        Thread thread = new Thread(futureTask);
        thread.start();*/

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }

        System.out.println("主线程在执行任务");

        try {
            System.out.println("task运行结果"+futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        System.out.println("所有任务执行完毕");
    }
}
class Task implements Callable<Integer>{
    @Override
    public Integer call() throws Exception {
        System.out.println("子线程在进行计算");
        Thread.sleep(3000);
        int sum = 0;
        for(int i=0;i<100;i++)
            sum += i;
        return sum;
    }
}

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn