Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Waiting for a thread to finish execution

Java newbie here. I am using a third party library which gives me a function, say F(), the output of which dictates my logic. So I need the result of it to proceed further in my code.

The problem is F() does some I/O and so spawns off a thread to do the functionality. They gave me a few callbacks to implement which are called to return the status/values from the thread. This is fine except that the function F() returns immediately and the rest of my code keeps running. I don't want that as I have to allocate some objects based on the outcome of F() and so I really want to wait for F() to really finish.

This should be a problem people run into quite often. What is the correct way to deal with this? Is it a problem in my design or the third party library? Or did I not understand the library very well?

For the sake of completeness I am working on an android app and the library is the facebook sdk. The function is the single sign-on function authorize(). Though this is a generic enough problem that I thought is best addressed in the Java forum.

Thanks for any help. - P

like image 925
user220201 Avatar asked Jan 19 '23 21:01

user220201


2 Answers

I'm not familiar with the facebook SDK, but the normal mechanism to handle async operations like this is the Callable<> or Future<> interface: you'd create a service executor, pass in the Callable<> or Future<>, and then continue with your code.

An example can be found from the Future<> javadoc: http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html

Also see StackOverflow question/answer How to return object from Callable()

like image 132
Joseph Ottinger Avatar answered Jan 22 '23 10:01

Joseph Ottinger


Think about this:
The main thread of an android app is the thread that manages the UI, so if you want to wait until the method f() finishes, the screen will freeze. You probably will think that a good solution is to spawn a new thread and call the method f() inside it and use a callable or future to wait f(). Wrong. The code below the thread creation will execute so you will have the same problem.
Then how can you solve this? Simple. Redesign your application and use a listener, a.k.a. callback.

EDIT: A listener or callback is just a method (or methods) that a class A implement and passes this implementation to a class B to execute it. Class B doesn't know what he is executing, he just executes a method.

Example:

public class A{
    public A (){
        B b = new B (new B.Listener (){
            @Override
            void onResult (String result){
                //result is "Core dumped!"
            }
        });
        b.aMethod ();
    }
}

public class B{
    private final Listener listener;

    public static interface Listener{
        void onResult (String result);
    }

    public B (Listener listener){
        if (listener == null) throw new IllegalArgumentException ("The \"listener\" parameter cannot be null.");
        this.listener = listener;
    }

    public void aMethod (){
        //Do something interesant
        //...
        String error = "Core dumped!"

        //Call the listener
        listener.onResult (error);
    }
}

In your case you will have something similar to this:

public class YourClass{
    public void aMethod (){
        FaceBookClass fb = new FaceBookClass ();
        fb.setListenerToF (new FaceBookClass.FListener (){
            @Override
            void theCallback (Result aResult){
                //Do something with result
            }
        });
        fb.f ();

    }
}

public class FaceBookClass{
    public static interface FListener{
        void theCallback (Result aResult);
    }

    public void f (){
        ...
    }

    public void setListenerToF (FListener listener){
        ...
    }
}
like image 43
Gabriel Llamas Avatar answered Jan 22 '23 12:01

Gabriel Llamas