从使用java的方法返回值(线程)

从使用java的方法返回值(线程),java,multithreading,concurrency,Java,Multithreading,Concurrency,我是线程概念的新手,我正在努力学习 我遇到了一个我 有一个返回学生列表的方法…和其他使用此列表来 提取学生的其他详细信息,如ParentsName,他们参加过的运动 etc(基于学生ID)。。我尝试使用以下代码返回一个列表,但它似乎不起作用:( import java.util.ArrayList; 公共类studentClass实现可运行 { 私人易变名单学生名单; @凌驾 公开募捐 { studentList=“返回studentList(StudentID、StudentName等)的My

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

我遇到了一个我 有一个返回学生列表的方法…和其他使用此列表来 提取学生的其他详细信息,如ParentsName,他们参加过的运动 etc(基于学生ID)。。我尝试使用以下代码返回一个列表,但它似乎不起作用:(

import java.util.ArrayList;
公共类studentClass实现可运行
{
私人易变名单学生名单;
@凌驾
公开募捐
{
studentList=“返回studentList(StudentID、StudentName等)的Mysql查询”;
}
公共列表getStudentList()
{
返回学生名单;
}
}
公共类主类
{
公共静态void main(字符串参数[])
{ 
StudentClass b=新的StudentClass();
新线程(b.start();
// ... 
List List=b.getStudentList();
学生班(sc:b)
{
系统输出打印LN(sc);
}
}
}
我使用了这个链接- 列表为空。

我哪里出错了…?

很可能您没有等待结果完成

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

Executors=Executors.newSingleThreadExecutor();
Future=es.submit(new Callable()){
公共列表调用()引发异常{
//做一些工作来获得这个列表
}
};
//做点什么
//等待结果。
List=future.get();
这就提供了更多的选择,比如

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

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

因为line
ArrayList list=b.getStudentList()会得到null;
在数据库查询发生之前执行,因为这是在单独的线程中发生的

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

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

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

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

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;
}}
public类MainClass
{
公共静态void main(字符串args[])引发异常
{
StudentClass b=新的StudentClass();
ExecutorService ExecutorService=Executors.newFixedThreadPool(3);
未来学生名单=执行服务。提交(b);
//当线程完成从DB中提取时,studentList将有记录
while(studentList.isDone())
{
System.out.println(“cooollll”+studentList.get());
}
}
}
公共类StudentClass实现了可调用{
私人易变名单学生名单;
公共列表getStudentList()
{
返回学生名单;
}
@凌驾
公共列表调用()引发异常
{
/**
*学生列表将从数据库获取
*/
studentList=newarraylist();
返回学生名单;
}}

studentList=“返回studentList(StudentID、StudentName等)的Mysql查询”;
它是否编译?在线程内是如果打印,它会显示…@6dsfds32当您在线程上调用
start()
时,您的程序会继续到下一行,而不等待线程完成。(这就是在线程中运行某些东西的全部意义。)因此,在线程的
运行()时调用
b.getStudentList()
方法可能尚未为
学生列表分配值。@ScaryWombat代码更改术语我同意。就使用的良好模式而言,我建议尽可能使用ExecutorService。ExecutorService es=Executor.newSingleThreadedPool();抛出错误newSingleThreadedPool()类型Executor未定义..:(@goodyzain这是一个编译器错误(不是throwm)告诉你我使用了错误的类(我现在已经修复了)谢谢你的帮助:):)如果我没有错的话…Executors类有newSingleThreadPool()吗????我想你需要为将来的用户更改方法名:):@goodyzain@Peter应该是
Executors.newSingleThreadExecutor()
;)如果这就是您想要的,您可以继续轮询列表,看看它是否仍然是
null
。有时我们的线程会执行许多查询,然后可能是您的列表不是空的,但这不是您所期望的。在这种情况下,您可以避免设置
列表
,直到它准备就绪。可能是其他地方需要不完整的结果。
Thread t = new Thread(new studentClass());
t.start();
t.join();
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;
}}