有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程Java让线程返回一些东西到主线程

我被什么事缠住了,似乎想不出解决办法。我有一个名为dbSelect的函数,它会创建一个线程来运行MySQL查询并获取一个ResultSet,但是我需要我的dbSelect来获取那个ResultSet并返回它。以下是我所拥有的:

public class Utils {
    public static void dbSelect(String query){
        selectQuery = query;
        Thread selectThread = new selectThreadClass();
        selectThread.start();
    }
}
class selectThreadClass extends Thread {
    public void run(){
        perform();
    }

    public ResultSet perform(){
        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver").newInstance();
            conn = DriverManager.getConnection("jdbc:mysql://localhost/lob/?user=root&password=");

            Statement s = conn.createStatement();
            ResultSet rs = s.executeQuery(Utils.selectQuery);
            return rs;
        }catch (SQLException | InstantiationException | IllegalAccessException | ClassNotFoundException e){
            e.printStackTrace();
            return null;
        }
    }
}

有谁能帮我得到它,以便dbSelect从线程返回ResultSet吗?谢谢


共 (5) 个答案

  1. # 1 楼答案

    使用Callable

     public interface Callable<V> {
     V call() throws Exception;
    }
    
  2. # 2 楼答案

    从我这边开始试试

    我修改了代码,得到了使用列表保存结果集值的解决方案,但我只有一个问题 也就是说,我无法在Callable中以type(ResultSet)的形式获得结果

    不知怎的,当我尝试去做时,结果集是空的 使用future get()函数检索值

    结果集rs=(结果集)未来。get()

    下面是一段不起作用的代码

    ExecutorService service=Executors.newFixedThreadPool(1);
    Callable<ResultSet> callable = new SelectThreadResultSet();
    Future<ResultSet> future = service.submit(callable);
    ResultSet rs = (ResultSet)future.get();
    // Here I dont get any values
    while(rs.next()){
        System.out.println(rs.getString("EMPLOYEE"));
    }
    

    请在下面找到适合我的解决方案,我使用了列表 保存并返回值

    类SelectThreadClass:

    public class SelectThreadClass implements Callable<List<String>> {
    
        public List<String> call(){
            ResultSet rs = null;
            List<String> strList = new ArrayList<String>();
            try {
                rs  = perform();
                while(rs.next()){
                    strList.add(rs.getString("EMPNAME"));
                }
                System.out.println("Passed");
    
            } catch (InstantiationException | IllegalAccessException | SQLException e) {
                e.printStackTrace();
            }
            return strList;
        }
    
        public ResultSet perform() throws InstantiationException, IllegalAccessException, SQLException{
            Connection conn = null;
            try {
                Class.forName("org.sqlite.JDBC");
                try {
                    conn = DriverManager.getConnection("jdbc:sqlite:C:\\SqlLite\\EMPLOYEE.db");
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    
                Statement s = null;
                try {
                    s = conn.createStatement();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                ResultSet rs = null;
                try {
                    rs = s.executeQuery(Utils.selectQuery);
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return rs;
            }catch (ClassNotFoundException e){
                e.printStackTrace();
                return null;
            }
        }
    }
    

    类别UTIL:

    public class Utils {
    
        public static String selectQuery = "SELECT EMPNAME FROM EMPLOYEEDETAILS";
        public static void dbSelect(String query) throws InterruptedException, ExecutionException, SQLException{
            ExecutorService service=Executors.newFixedThreadPool(1);
            Callable<List<String>> callable = new SelectThreadClass();
    
            Future<List<String>> future = service.submit(callable);
    
            List<String> empList = future.get();
            for(String emp : empList){
                System.out.println(emp);
            }
        }
    
        public static void main(String args[]) throws InterruptedException, ExecutionException, SQLException{
            dbSelect("SELECT EMPNAME FROM EMPLOYEEDETAILS");
        }
    
    }
    
  3. # 3 楼答案

    使用callable代替Runnable

    public class SelectCallableClass implements Callable<ResultSet> {
    
        public ResultSet call() throws Exception {
            return perform();
        }
    
        public ResultSet perform(){
            Connection conn = null;
            try {
                Class.forName("com.mysql.jdbc.Driver").newInstance();
                conn = DriverManager.getConnection("jdbc:mysql://localhost/lob/?user=root&password=");
    
                Statement s = conn.createStatement();
                ResultSet rs = s.executeQuery(Utils.selectQuery);
                return rs;
            }catch (SQLException | InstantiationException | IllegalAccessException | ClassNotFoundException e){
                e.printStackTrace();
                return null;
            }
        }
    }
    

    要提交可调用类,请使用ExecuterService

    ExecutorService service=Executors.newFixedThreadPool(1);
    Future future=service.submit(new SelectCallableClass());
    

    The above code does the following(from doc).Submits a value-returning task for execution and returns a Future> representing the pending results of the task. The Future's get method will return the task's result upon successful completion.

  4. # 4 楼答案

    你只需要在你的线程类中有一个属性,然后获得该属性

    public class Utils {
        public static void dbSelect(String query){
            selectQuery = query;
            Thread selectThread = new selectThreadClass();
            selectThread.start();
    
            ((SelectThreadClass) selectThread).getResult();
        }
    }
    
    class selectThreadClass extends Thread {
        ResultSet rs = null;
    
        public ResultSet getResult(){
            return rs;
        }
    
        public void run(){
            rs = perform();
        }
    
        public ResultSet perform(){
            Connection conn = null;
            try {
                Class.forName("com.mysql.jdbc.Driver").newInstance();
                conn = DriverManager.getConnection("jdbc:mysql://localhost/lob/?user=root&password=");
    
                Statement s = conn.createStatement();
                return s.executeQuery(Utils.selectQuery);
            } catch (SQLException | InstantiationException | IllegalAccessException | ClassNotFoundException e){
                e.printStackTrace();
                return null;
            }
        }
    }
    

    唯一的问题是,您可能最终会从dbutil中处理连接闭包和其他内容,或者,您可以将结果集转换为任何java类,然后返回该java对象列表,而不是结果集

  5. # 5 楼答案

    run不返回结果
    使用alCallable或使用共享变量并在Utils中轮询wait,直到SelectThreadClass的结果可用
    但是我建议使用Callable,因为它完全适合这个任务