【问题标题】:How to read data from database using multiple thread in java如何在java中使用多线程从数据库中读取数据
【发布时间】:2018-01-10 13:50:42
【问题描述】:

如何使用多个线程从数据库中读取数据,我在 DB 中有 16 个表,我想使用多个线程从这些表中并行读取数据。

【问题讨论】:

  • 让每个线程打开自己的连接并进行独立查询。但是,我怀疑这是否会有很大帮助。性能很可能受到 I/O 的限制,因此您不应该期望它在使用 N 个线程时会快 N 倍。
  • 这个问题是方式广泛。整本书都是关于这些主题的。做一些真正的研究,欢迎你回来提出一个真正的具体问题。

标签: java multithreading jdbc concurrency


【解决方案1】:

这是创建我们如何使用 2 个线程和 2 个表的示例。同样,您可以将它用于多个表。

只需要一个连接,因为我们只是从表中读取,而不是从表中更新或插入或删除。

public class ClearPoppup implements Runnable {

    Connection c;

    private static final String DB_DRIVER = "com.mysql.jdbc.Driver";
    private static final String DB_CONNECTION = "jdbc:mysql://localhost:3306/project";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "****";

    public ClearPoppup() {

        try {
            Class.forName(DB_DRIVER);
            c = DriverManager.getConnection(DB_CONNECTION, DB_USER, DB_PASSWORD);
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ClearPoppup impClass = new ClearPoppup();

        Thread t1 = new Thread(impClass) {
            public void run() {

                Statement s;
                try {
                    s = impClass.c.createStatement();
                    ResultSet rs = s.executeQuery("select * from user");
                    while (rs.next())
                        System.out.println(rs.getInt(1) + "  " + rs.getString(2) + "  " + rs.getString(3));
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        };

        Thread t2 = new Thread() {
            public void run() {
                Statement s;
                try {
                    s = impClass.c.createStatement();
                    ResultSet rs = s.executeQuery("select * from userprofile");
                    while (rs.next())
                        System.out.println(rs.getInt(1) + "  " + rs.getString(2) + "  " + rs.getString(3));

                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }

        };

        t1.start();
        t2.start();

    }

    @Override
    public void run() {
        // TODO Auto-generated method stub

    }
}

【讨论】:

    【解决方案2】:

    创建一个分区器,它将您的所有数据集划分为多个子组,这些子组将由单线程处理。

    创建单个任务并通过executorservice执行。

    使用 countdownlatch 停止主线程,直到所有任务完成。

    使用大小与线程池相当的连接池。

    public class  Partitioner {
    
        @Override
        public Map<String, SomeDomainObject> partition(int size) {
    
            Map<String, SomeDomainObject> result
                           = new HashMap<String, SomeDomainObject>();
    
            int range = 10;//calculate your range depending on threadsize.
            int fromId = 1;
            int toId = range;
    
            for (int i = 1; i <= size; i++) {
                SomeDomainObject value = new SomeDomainObject();
                value.setFromId(fromId);
                value.setToId(toId);
                value.setThreadName("Thread" + i);
                result.put("partition" + i, value);
                fromId = toId + 1;
                toId += range;
    
            }
    
            return result;
        }
    

    【讨论】:

      【解决方案3】:

      您有多种选择。

      1. 在每个线程中创建一个新连接。
      2. 创建连接池,根据需要从线程中获取连接。
      3. 在线程中使用之前创建一个连接并synchronize。这不允许您“并行”读取数据库,但它允许您跨线程使用相同的连接。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-12-21
        • 1970-01-01
        • 1970-01-01
        • 2020-12-27
        • 2021-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多