goodyzain
goodyzain

Reputation: 673

Returning Value From a Method Using java(Threads)

I am newbie to threading Concept, and I am trying learn....

I came across a situation where i have a Method which returns a List Of Students...and other methods which uses this List to pull Other Details of students Like ParentsName, Sports in which they have participated etc (based on StudentID).. I tried returning a list using following code and it seems like it's not working :(

import java.util.ArrayList;

public class studentClass implements Runnable
{
    private volatile List<Student> studentList;

    @Override
    public void run() 
    {
        studentList = "Mysql Query which is returning StudentList(StudentID,StudentName etc)";  
    }

    public List<Student> getStudentList()
    {
        return studentList;
    }
}

public class mainClass 
{
   public static void main(String args[])
   { 
       StudentClass b = new StudentClass();
       new Thread(b).start();
       // ... 
       List<Student> list = b.getStudentList();
       for(StudentClass sc : b)
       {
           System.out.println(sc);
       }
   }
}

I used this Link - Returning value from Thread the list is NULL.
Where am I going Wrong...???

Upvotes: 2

Views: 275

Answers (4)

Peter Lawrey
Peter Lawrey

Reputation: 533530

Most likely you are not waiting for the result to complete.

A simple solution is to use an ExecutorService instead of creating your own thread pool.

See http://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executors.html#newSingleThreadExecutor--

ExecutorService es = Executors.newSingleThreadExecutor();

Future<List<Student>> future = es.submit(new Callable<List<Student>>() {
     public List<Student> call() throws Exception {
          // do some work to get this list
     }
};

// do something

// wait for the result.
List<Student> list = future.get();

This gives to lots more options such as

  • capture any exception thrown so you know what went wrong.
  • pool isDone() to see if it is ready
  • call get() with a tiemout.
  • have a thread pool which re-uses the thread or has more than one thread.

Upvotes: 7

sendon1982
sendon1982

Reputation: 11234

In the code example, if StudentClass run method will take some seconds, you will print empty since list has not been set.

public class MainClass
{

    public static void main(String args[]) throws Exception
{

    StudentClass b = new StudentClass();

    ExecutorService executorService = Executors.newFixedThreadPool(3);
    Future<List<Student>> studentList = executorService.submit(b);

    // When the thread completed fetching from DB, studentList will have records
    while(studentList.isDone())
    {
        System.out.println("COoolllll" + studentList.get());
    }
}
}

public class StudentClass implements Callable<List<Student>>{

private volatile List<Student> studentList;

public List<Student> getStudentList()
{
    return studentList;
}

@Override
public List<Student> call() throws Exception
{
    /**
     * studentList will fetch from DB
     */
    studentList = new ArrayList<Student>(); 
    return studentList;
}}

Upvotes: 0

Chathurika Sandarenu
Chathurika Sandarenu

Reputation: 1512

You are getting null since line ArrayList<student> List=b.getStudentList(); is executed before your DB quering happens because that is happening in a separate thread.

You have to wait till database query thread execution finishes. One way to do is to use join() method on the thread.

Thread t = new Thread(new studentClass());
t.start();
t.join();

Or you can use Callable interface provided with Java to return value from a thread. Refer this article as a starting point.

Upvotes: 2

ConductedClever
ConductedClever

Reputation: 4295

I think it is good idea to have an global instance of the students list, then call the thread to fill it, and have another bool variable to recognize that the threads work is done or not or something like this.

Upvotes: -1

Related Questions