web-dev-qa-db-fra.com

java Méthode runnable run () renvoyant une valeur

Selon la documentation Java, la méthode Runnable, void run(), ne peut pas renvoyer de valeur. Je me demande toutefois s'il existe une solution de rechange à cela. 

En fait, j'ai une méthode qui appelle:

public class Endpoint{
    public method_(){
       RunnableClass runcls = new RunnableClass();
       runcls.run()
    }
}

dont la méthode run() est:

public class RunnableClass implements Runnable{

    public jaxbResponse response;
        public void run() {
            int id;
            id =inputProxy.input(chain);
            response = outputProxy.input();

        }
}

Je veux avoir accès à la variable response dans method_() est-ce possible?

36
Grzzzzzzzzzzzzz

Utilisez Callable<V> au lieu d'utiliser Runnable interface.

Exemple:

public static void main(String args[]) throws Exception {
    ExecutorService pool = Executors.newFixedThreadPool(3);
    Set<Future<Integer>> set = new HashSet<Future<Integer>>();
    for (String Word: args) {
      Callable<Integer> callable = new WordLengthCallable(Word);
      Future<Integer> future = pool.submit(callable);
      set.add(future);
    }
    int sum = 0;
    for (Future<Integer> future : set) {
      sum += future.get();
    }
    System.out.printf("The sum of lengths is %s%n", sum);
    System.exit(sum);
  }

Dans cet exemple, vous devrez également implémenter la classe WordLengthCallable, qui implémente l'interface Callable.

50
Narendra Pathai
public void check() {
    ExecutorService executor = Executors.newSingleThreadExecutor();
    Future<Integer> result = executor.submit(new Callable<Integer>() {
        public Integer call() throws Exception {
            return 10;
        }
    });

    try {
        int returnValue = result.get();
    } catch (Exception exception) {
       //handle exception
    }
}
14
vishal_aim

Jetez un coup d'oeil à la classe Callable . Ceci est généralement soumis via un service executor

Il peut retourner un futur objet qui est retourné quand le thread se termine

6
RNJ

Si vous ajoutez un champ à RunnableClass, vous pouvez le définir dans run et le lire dans method_. Cependant, Runnable est un pauvre (mot-clé Java) interface car il ne vous dit rien sur l’interface (le concept) (seule ligne utile de la documentation de l’API: "Le contrat général de la méthode run est qu’elle peut entreprendre une action quelconque. "). Il vaut mieux utiliser une interface plus significative (qui peut renvoyer quelque chose).

3

Oui, il existe des solutions de contournement. Utilisez juste la file d’attente et mettez-y la valeur que vous voulez renvoyer. Et prenez cette valeur d'un autre thread.

public class RunnableClass implements Runnable{

        private final BlockingQueue<jaxbResponse> queue;


        public RunnableClass(BlockingQueue<jaxbResponse> queue) {
            this.queue = queue;
        }

        public void run() {
            int id;
            id =inputProxy.input(chain);
            queue.put(outputProxy.input());
        }
    }


    public class Endpoint{
        public method_(){
            BlockingQueue<jaxbResponse> queue = new LinkedBlockingQueue<>();

            RunnableClass runcls = new RunnableClass(queue);
            runcls.run()

            jaxbResponse response = queue.take(); // waits until takes value from queue
        }
    }
1
Eldar Agalarov

Une façon est, nous devons utiliser l'approche Future - Callable.

Au lieu de renvoyer une valeur, vous pouvez également conserver un objet.

Exemple:

class MainThread {
    public void startMyThread() {
        Object requiredObject = new Object(); //Map/List/OwnClass
        Thread myThread = new Thread(new RunnableObject(requiredObject)).start();
        myThread.join();

        System.out.println(requiredObject.getRequiredValue());    
    }
}



class RunnableObject implements Runnable {
    private Object requiredObject;

    public RunnableObject(Object requiredObject) {
        this.requiredObject = requiredObject;
    }

    public void run() {
        requiredObject.setRequiredValue(xxxxx);
    }
}

Parce que la portée de l'objet est dans la même portée, vous pouvez donc transmettre un objet à thread et récupérer dans la portée principale. Mais le plus important est que nous devons utiliser la méthode join (). Parce que la portée principale devrait attendre la fin de la tâche du thread. 

Dans le cas de plusieurs threads, vous pouvez utiliser List/Map pour conserver les valeurs des threads. 

1
ramakrishna

Essayez ce qui suit

public abstract class ReturnRunnable<T> implements Runnable {

    public abstract T runForResult();

    @Override
    public void run() {
        runForResult();
    }
}
0
Martin

Jetez un coup d'œil à l'interface appelable , peut-être que cette solution répond à vos besoins. Vous pouvez également essayer d'obtenir la valeur du champ de réponse en appelant une méthode setter à l'intérieur de votre méthode run().

public void run() {
    int id;
    id =inputProxy.input(chain);
    response = outputProxy.input();
    OuterClass.setResponseData(response);

}
0
htz