2 votes

FutureTask interne en Java

Je essaie de mettre en œuvre une méthode interne afin d'exécuter le code suivant dans un nouveau thread

MyPojo result = null;
final MyPojo result2 = result;

FutureTask runnableTask = new FutureTask(
    new Runnable() {  

        BindJSON binding;

        // Make the URL at which the product list is found
        String sourceURLString = 
            "http://www.....ca/files/{CAT_ID}.json";                

        @Override
        public void run() {  
            sourceURLString = sourceURLString.replace("{CAT_ID}", catId);
            binding = new BindJSON();  
            result2 = binding.downloadData(sourceURLString, MyPojo.class);  
        }  
    }, 
    result2);

runnableTask.run();

Donc, maintenant je reçois une erreur qui dit : La variable locale finale result2 ne peut pas être assignée, car elle est définie dans un type englobant. J'ai consulté cette réponse : Cannot refer to a non-final variable i inside an inner class defined in a different method mais cela n'a pas fonctionné pour moi. Que dois-je faire pour que cela fonctionne?

4voto

miku Points 63392

Vous voudrez peut-être utiliser un Callable, pas un Runnable:

// the variable holding the result of a computation
String result = null;

FutureTask runnableTask = new FutureTask(
        new Callable() {
            public String call() throws Exception {
                // (asynchronous) computation ...
                return "42";
            }
        });

System.out.println("result=" + result); // result=null

// this will invoke call, but it will all happen in the *same thread*
runnableTask.run();

// to have a parallel thread execute in the 'background'
// you can use java.util.concurrent.Executors
// Note: an ExecutorService should be .shutdown() properly
// Executors.newSingleThreadExecutor().submit(runnableTask);

// waits for the result to be available
result = runnableTask.get();

// you can also add timeouts:
// result = runnableTask.get(100, TimeUnit.MILLISECONDS);

System.out.println("result=" + result); // result=42

3voto

assylias Points 102015

Votre utilisation de FutureTask n'est pas très utile car vous l'exécutez dans le même thread. Vous pourriez utiliser un exécuteur et soumettre un callable pour obtenir ce que vous voulez :

    ExecutorService executor = Executors.newFixedThreadPool(1);

    Callable task = new Callable () {
        BindJSON binding;
        // Faites l'URL où la liste de produits est trouvée
        String sourceURLString = "http://www.....ca/files/{CAT_ID}.json";

        @Override
        public MyPojo call() {
            sourceURLString = sourceURLString.replace("{CAT_ID}", catId);
            binding = new BindJSON();
            return binding.downloadData(sourceURLString, MyPojo.class);
        }
    };

    Future future = executor.submit(task);
    MyPojo result = future.get();

Remarque : l'appel à future.get(); bloquera jusqu'à ce que la tâche soit terminée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X