Maison Java javaDidacticiel La relation et l'utilisation entre Future et FutureTask en Java (avec code)

La relation et l'utilisation entre Future et FutureTask en Java (avec code)

Oct 15, 2018 pm 03:46 PM
java

Le contenu que cet article vous apporte concerne la relation et l'utilisation entre Future et FutureTask en Java (avec du code). Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer. .

Future et FutureTask sont tous deux utilisés pour obtenir les résultats de retour de l'exécution du thread. Ci-dessous, nous donnerons une introduction générale et une analyse de la relation et de l'utilisation entre les deux

1 Future et Introduction à FutureTask :

Future se trouve sous le package java.util.concurrent, qui est une interface

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;
}
Copier après la connexion

Il existe 5 méthodes déclarées dans l'interface Future. La fonction de chaque méthode est présentée ci-dessous :

La méthode Cancel est utilisée pour annuler la tâche. Elle renvoie true si l'annulation est réussie et false si. l'annulation échoue. Le paramètre mayInterruptIfRunning est défini sur false, ce qui signifie que l'interruption n'est pas autorisée lorsque le thread est en cours d'exécution, et défini sur true, ce qui signifie qu'elle est autorisée. Plus précisément, il peut être divisé selon les trois situations suivantes :

1. Si la tâche est terminée, que mayInterruptIfRunning soit vrai ou faux, elle retournera faux. C'est parce que la tâche que vous souhaitez annuler a été. terminée et l'annulation de la tâche est considérée comme ayant échoué. ;

2. Si la tâche est en cours d'exécution, true sera renvoyé, que mayInterruptIfRunning soit vrai ou faux. C'est juste que lorsque mayInterruptIfRunning est vrai, le thread sera interrompu, et lorsqu'il est faux, le thread ne sera pas interrompu et terminera son exécution.

3. Si la tâche n'a pas été exécutée, que mayInterruptIfRunning soit vrai ou faux, elle retournera vrai.

La méthode isCancelled est utilisée pour déterminer si la tâche a été annulée avec succès. Si la méthode Cancel réussit, elle renvoie vrai, sinon elle renvoie faux.

isDone est utilisé pour déterminer si la tâche est terminée et renvoie vrai si la tâche est terminée. L'achèvement de la tâche inclut l'achèvement normal, l'annulation de la tâche et l'exception de tâche, tous renvoyant vrai

La méthode get() est utilisée pour obtenir le résultat de l'exécution. Cette méthode provoquera un blocage et ne reviendra que lorsque l'exécution de la tâche sera terminée. ;

get(long timeout, TimeUnit unit) est utilisé pour obtenir le résultat de l'exécution. Si le résultat n'est pas obtenu dans le délai spécifié, une exception java.util.concurrent.TimeoutException sera levée

FutureTask implémente l'interface RunnableFuture, et RunnableFuture hérite des interfaces Future et Runnable, donc FutureTask implémente non seulement toutes les méthodes de l'interface Future diagramme de classes

II, Future et FutureTaskUtilisation et analyse

1. Lors de l'utilisation de Future, nous devons implémenter l'interface Callable et obtenir l'objet Future renvoyé via la méthode de soumission de l'interface ExecutorService

2. , selon le constructeur de FutureTask, nous pouvons voir que FutureTask a les deux. Vous pouvez recevoir la classe d'implémentation de Callable ou la classe d'implémentation de Runnable. Lorsque vous transmettez la classe d'implémentation de Callable, vous pouvez obtenir le résultat de l'exécution du thread ; lorsque vous transmettez la classe d'implémentation de Runnable, puisque l'implémentation de Runnable n'a pas de valeur de retour, vous devez transmettre un identifiant d'achèvement de thread que vous avez défini. , qui est le résultat. Ensuite, lorsque le fil de discussion se termine, la valeur du résultat d'origine que vous avez transmise vous sera renvoyée. Le constructeur de FutureTask est le suivant :

public class FutureTask<V> implements RunnableFuture<V>{
     public FutureTask(Callable<V> callable) {
        if (callable == null)
            throw new NullPointerException();
        this.callable = callable;
        this.state = NEW;       // ensure visibility of callable
     }
     public FutureTask(Runnable runnable, V result) {
        this.callable = Executors.callable(runnable, result);//runnable转化为callable 
        this.state = NEW;       // ensure visibility of callable
     }
}
Copier après la connexion

.

Ensuite, nous verrons ci-dessous les codes d'utilisation spécifiques pour Future et FutureTask :

       // 执行任务 实现Runnable
        FutureTaskJobRunnable taskRun = new FutureTaskJobRunnable();
        // 执行任务 实现Callable
        FutureTaskJobCallable taskCall = new FutureTaskJobCallable();
        String val = "ok";
        // 线程运行成功后把,返回你传入的val值
        FutureTask<String> futureTaskRun = new FutureTask<String>(taskRun, val);
        // 线程运行,返回线程执行的结果
        FutureTask<String> futureTaskCall = new FutureTask<String>(taskCall);
        //声明线程池
        ExecutorService executor = Executors.newCachedThreadPool();        
        //Future
        Future<String> future =  executor.submit(taskCall);
        System.out.println(future.get());
        //FutureTask
        executor.submit(futureTaskCall);
        System.out.println(futureTaskCall.get());
        //FutureTask自定义线程执行
        new Thread(futureTaskRun).start();
        System.out.println(futureTaskRun.get());
Copier après la connexion

public class FutureTaskJobCallable implements Callable<String>{
    
    public String call() throws Exception {
        System.out.println("FutureTaskJobCallable已经执行了哦");
        Thread.sleep(1000);
        return "返回结果";
    }
}
public class FutureTaskJobRunnable implements Runnable {
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("FutureTaskJobRunnable已经执行了哦");
    }
}
Copier après la connexion

Selon le code ci-dessus, nous commençons par la méthode submit dans l'interface ExecutorService et examinons l'implémentation spécifique de la méthode submit dans la classe AbstractExecutorService.

public Future<?> submit(Runnable task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<Void> ftask = newTaskFor(task, null);
        execute(ftask);
        return ftask;
    }
    public <T> Future<T> submit(Runnable task, T result) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task, result);
        execute(ftask);
        return ftask;
    }
    public <T> Future<T> submit(Callable<T> task) {
        if (task == null) throw new NullPointerException();
        RunnableFuture<T> ftask = newTaskFor(task);
        execute(ftask);
        return ftask;
    }
    protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
        return new FutureTask<T>(runnable, value);
    }
    protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
        return new FutureTask<T>(callable);
    }
Copier après la connexion

Vous pouvez voir que lorsque vous utilisez la méthode submit pour soumettre une tâche, elle sera convertie en un objet FutureTask via la méthode newTaskFor, donc analysons le code ci-dessus en détail Trois situations :

1. Si vous transmettez la classe Runaable ou la classe Callable implémentée par vous-même, alors la méthode sumbit vous aidera naturellement à l'encapsuler automatiquement dans un objet FutureTask, et à obtenir le résultat via l'objet Future après l'exécution.

2、你传入的已经是个自己构造的FutureTask对象,由于FutureTask其实是实现了Runnable接口的,它本身就是个Runaable实现类, sumbit方法还是会将它视为Runnable类来进行封装,并最终会执行FutureTask自己的run方法,一系列实现都在你传入的FutureTask对象内完成,所以你可以直接通过自己构建的FutureTask获取结果;

3、自己单独声明线程运行,跟第2点类似,FutureTask本身就是个Runnabel实现类,自然可以做为参数传入Thread运行;

那么我们把自定义的Runnable、Callable实现类做为参数构造FutureTask后,FuttureTask是如何运行的呢,我们可以看下FuttureTask中具体的代码实现

//你传入的Runnable与Callable实现类都会在构造函数中转化为Callable
private Callable<V> callable;
    public void run() {
        if (state != NEW ||
            !UNSAFE.compareAndSwapObject(this, runnerOffset,
                                         null, Thread.currentThread()))
            return;
        try {
            Callable<V> c = callable;//你传入的实现类
            if (c != null && state == NEW) {
                V result;//返回值
                boolean ran;
                try {
                    result = c.call();//运行后返回结果
                    ran = true;
                } catch (Throwable ex) {
                    result = null;
                    ran = false;
                    setException(ex);
                }
                if (ran)
                    set(result);
            }
        } finally {
            // runner must be non-null until state is settled to
            // prevent concurrent calls to run()
            runner = null;
            // state must be re-read after nulling runner to prevent
            // leaked interrupts
            int s = state;
            if (s >= INTERRUPTING)
                handlePossibleCancellationInterrupt(s);
        }
    }
Copier après la connexion

可以看到FutureTask类本身的run方法,就是执行Runnable、Callable的实现类并获取返回结果的过程。

所以ExecutorService接口中submit方法归根结底还是要把你传入的对象封装成FutureTask对象,并通过FutureTask类的内部实现来获取结果的,返回的Future接口对象也要依赖于FutureTask实例化的,所以无论是直接传入自己的Runnable、Callable实现类还是构建FutureTask传入,本质上都是通过FutureTask去实现,没有什么区别;

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

Video Face Swap

Video Face Swap

Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Nombre parfait en Java Nombre parfait en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Weka en Java Weka en Java Aug 30, 2024 pm 04:28 PM

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Numéro de Smith en Java Numéro de Smith en Java Aug 30, 2024 pm 04:28 PM

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Questions d'entretien chez Java Spring Questions d'entretien chez Java Spring Aug 30, 2024 pm 04:29 PM

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Break or Return of Java 8 Stream Forach? Break or Return of Java 8 Stream Forach? Feb 07, 2025 pm 12:09 PM

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

Horodatage à ce jour en Java Horodatage à ce jour en Java Aug 30, 2024 pm 04:28 PM

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

Programme Java pour trouver le volume de la capsule Programme Java pour trouver le volume de la capsule Feb 07, 2025 am 11:37 AM

Les capsules sont des figures géométriques tridimensionnelles, composées d'un cylindre et d'un hémisphère aux deux extrémités. Le volume de la capsule peut être calculé en ajoutant le volume du cylindre et le volume de l'hémisphère aux deux extrémités. Ce tutoriel discutera de la façon de calculer le volume d'une capsule donnée en Java en utilisant différentes méthodes. Formule de volume de capsule La formule du volume de la capsule est la suivante: Volume de capsule = volume cylindrique volume de deux hémisphères volume dans, R: Le rayon de l'hémisphère. H: La hauteur du cylindre (à l'exclusion de l'hémisphère). Exemple 1 entrer Rayon = 5 unités Hauteur = 10 unités Sortir Volume = 1570,8 unités cubes expliquer Calculer le volume à l'aide de la formule: Volume = π × r2 × h (4

PHP vs Python: comprendre les différences PHP vs Python: comprendre les différences Apr 11, 2025 am 12:15 AM

PHP et Python ont chacun leurs propres avantages, et le choix doit être basé sur les exigences du projet. 1.Php convient au développement Web, avec une syntaxe simple et une efficacité d'exécution élevée. 2. Python convient à la science des données et à l'apprentissage automatique, avec une syntaxe concise et des bibliothèques riches.

See all articles