Reputation: 673
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
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.
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
isDone()
to see if it is readyUpvotes: 7
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
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
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