使用java(Threads)从方法返回值

时间:2014-07-15 06:52:38

标签: java multithreading concurrency

我是线程概念的新手,我正在努力学习......

我遇到了一个情况  有一个方法,它返回一个学生列表...和其他使用此列表的方法     拉其他学生的详细信息像他们参加过的体育名称,体育 etc(基于StudentID)..我尝试使用以下代码返回列表,似乎它不起作用:(

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

我使用此链接 - Returning value from Thread 列表为NULL 我哪里错了...... ???

4 个答案:

答案 0 :(得分:7)

很可能你不是在等待结果完成。

一个简单的解决方案是使用ExecutorService而不是创建自己的线程池。

请参阅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();

这提供了更多选项,例如

  • 捕获任何抛出的异常,以便您知道出了什么问题。
  • isDone()以查看是否已准备就绪
  • 使用tiemout调用get()。
  • 有一个线程池,可以重用线程或有多个线程。

答案 1 :(得分:2)

由于行数ArrayList<student> List=b.getStudentList();在数据库查询发生之前执行,因此会在单独的线程中发生,因此您将获得null。

您必须等到数据库查询线程执行完成。一种方法是在线程上使用join()方法。

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

或者您可以使用Java提供的Callable接口从线程返回值。请参考this article作为起点。

答案 2 :(得分:0)

在代码示例中,如果StudentClass run方法需要几秒钟,您将打印为空,因为尚未设置列表。

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

答案 3 :(得分:-1)

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