简体   繁体   中英

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...???

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.

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.

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;
}}

我认为最好有一个学生列表的全局实例,然后调用线程填充它,并有另一个bool变量来识别线程的工作是否完成或类似的事情。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM