How to recover the return result of a routine from within a Thread?

Asked

Viewed 1,845 times

3

I need to run a routine within a Thread, and get the return of this method. My code is like this.

class Main {
    public static void main(String[] args) {
        String resultado = "";
        Thread t = new Thread() {
            @Override
            public void run(){
                //varios processamentos
                String strDeRetorno = "abcde";///
                //???? Como retornar esse valor ao final da execucao??
            }
        };
        //Como recuperar o valor retornado pelo método run da Thread??
        t.start();
    }
}

Note that it is not a case of declaring some type of global variable and changing it, even because there are no "global variables" in java. I really want to get the return value of the routine when it is finished.

  • The only way I know it is with recording in the database.

  • 3

    What do you mean? Be more specific and give an example of what you want to do.

  • 1

    First, there is no such thing as a "global variable". In fact, we are talking about "Shared Data". Data shared between multiple Threads. Probably you are referring to public and static variables. Try to improve your question, what are you doing, what don’t you understand? What do you mean "they don’t work"?

  • 1

    Can you elaborate better because you claim that they don’t work? They don’t work in what sense? I’m thinking about answering that question, but I have a lot of uncertainty as to whether the answer I’m going to write will do. I was thinking about talking about the modifier volatile, variables final effect, local variables vs instance vs static... But will what you really want is this?

  • 2

    Hello @daniel12345smith, I will answer your question here, IE, answer as an answer to this question, because the other was blocked. I think I understand your goal: return the result value of the Thread execution.

  • I just edited your question, as soon as you approve I’ll answer.

  • @Guilhermenascimento I wrote the author’s question code myself, I wrote this wrong code there, rs. If possible, correct, or let me correct. Thank you.

  • Perfect, thanks for the tips @Guilhermenascimento Leave more detailed, in this specific case, this whole code I wrote, so I think it would be interesting to edit it myself, not the author, even why I rephrased his question. At last, thanks again.

  • @Filipegonzagamiranda edited, good night.

  • @daniel12345smith , the question is in agreement with your initial question?

Show 5 more comments

2 answers

6

This functionality is achieved through the use of Threads pools, available in Java, from version 1.5 on Executors Framework

Instead of creating a Thread, you create a Pool with a Thread, and submits to it the tasks that you want this Thread to perform. For this your routine should implement a Callable<T>. This is a simple interface, which has a method call, the equivalent of run that you would implement into a common Thread, only with a subtle and powerful difference: It allows you to return a value of a kind.

V call() throws Exception;

Let’s go to the code:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Main {
    public static void main(String[] args) throws Exception{
        String resultado = "";

        //Criando um pool de Threads com uma Thread, 
        //equivalente ao sua Thread
        ExecutorService executor = Executors.newSingleThreadExecutor();

        //ao inves de chamarmos o metodo Thread.start(), chamamos:
        //executor.submit -> o que já permitirá que você obtenha um envólucro para
        //o resultado
        Future<String> futureResult = executor.submit(new Callable<String>() {

            //Note como este não é um Runnable, e sim um Callable("primo" do Runnable)
            @Override
            public String call() throws Exception {
                String retorno = "";
                //processando
                //sua lógica
                // e assim por diante
                retorno = "abcde";
                return retorno;
            }
        });

        //Obtendo um resultado da execucão da Thread
        resultado = futureResult.get();

        System.out.println(resultado);

        //lembrar de chamar o shutodown no executor - para encerrar a
        //execucão
        executor.shutdown();
    }
}

The moment you submit your routine, the method ExecutorService.submit will give you a Future

This Future object will give you access to the return value of this callable that was executed by your Thread. This will be done by calling the method Future.get()

Remember to call: executor.shutdown - This will shut down the Pool, which will also prevent new tasks from being performed.

*Please also read the comments in the example code. They should help you understand what is happening.

1

The variable is global, but cannot be accessed by different Threads at the same time. For this to happen, the global variable must be declared as volatile.
To pass parameters from one Thread to another, use Observer and Observable Follows: http://docs.oracle.com/javase/7/docs/api/java/util/Observer.html
Here is an example of implementation:

public class Observador implements Observer
{
    public static void main(String[] args) 
    {
        final Observador main = new Observador();
        final Thread thread = new Thread(new Observado(main));
        thread.start();
    }

    @Override
    public void update(Observable o, Object arg) 
    {
        if(arg != null){
            System.out.println(arg);
        }
    }

    public static class Observado extends Observable implements Runnable
    {
        /**
         * Recebe quem irá receber as notificações....
         * @param o
         */
        public Observado(final Observer o) 
        {
            addObserver(o);
        }
        @Override
        public void run() 
        {
            int pt = 0;
            while(pt != 5){
                final Random random  = new Random();
                // gera um numero aleatorio 
                final Integer num =  random.nextInt();
                setChanged();
                //envia ao observador 
                notifyObservers(num);
                pt++;
            }

        }
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.