Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用CountDownLatch和ExecutorService类在DB中插入100K条记录_Java_Multithreading - Fatal编程技术网

Java 使用CountDownLatch和ExecutorService类在DB中插入100K条记录

Java 使用CountDownLatch和ExecutorService类在DB中插入100K条记录,java,multithreading,Java,Multithreading,我必须从一个有超过100K条记录的ArrayList中插入一些DB值。我使用下面给出的CountDownLatch和ExecutorService类一次运行10个线程,以提高插入时的性能。我正在调用一个存储过程,在对详细信息进行一些处理之后,将员工详细信息插入到两个不同的表中。这是否符合我的要求 public static void writeData(List<Employee> empList) throws SQLException { Connection con

我必须从一个有超过100K条记录的ArrayList中插入一些DB值。我使用下面给出的CountDownLatch和ExecutorService类一次运行10个线程,以提高插入时的性能。我正在调用一个存储过程,在对详细信息进行一些处理之后,将员工详细信息插入到两个不同的表中。这是否符合我的要求

 public static void writeData(List<Employee> empList) throws SQLException {
    Connection con = null;
    try {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "system", "oracle");

        final CountDownLatch latch = new CountDownLatch(empList.size());
        ExecutorService taskExecutor = Executors.newFixedThreadPool(10);

        final CallableStatement cstmt = con.prepareCall("{Call Prc_Insert_Employee(?,?,?)}");

        for (int i = 0; i < empList.size(); i++) {
            final Employee emp = empList.get(i);

            Thread worker = new Thread() {
                public void run() {
                    try {
                        cstmt.setString(1, emp.getId());
                        cstmt.setString(2, emp.getName());
                        cstmt.setString(2, emp.getAge());
                        cstmt.executeUpdate();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                    finally{
                        latch.countDown();
                    }
                }
            };
            taskExecutor.execute(worker);
        }
        taskExecutor.shutdown();
        latch.await();
    } catch (Exception e) {
        System.out.println(e);
    } finally {
        con.close();
    }
}
publicstaticvoidwritedata(List-empList)抛出SQLException{
连接con=null;
试一试{
类forName(“oracle.jdbc.driver.OracleDriver”);
con=DriverManager.getConnection(“jdbc:oracle:thin:@localhost:1521:xe”、“system”、“oracle”);
final CountDownLatch latch=新的CountDownLatch(empList.size());
ExecutorService taskExecutor=Executors.newFixedThreadPool(10);
最终CallableStatement cstmt=con.prepareCall({呼叫中国插入员工(?,?)});
对于(int i=0;i
以下是我对您的代码的所有评论:

<> LI>你应该考虑使用<代码> AdBuffChh()/代码>而不是<代码> ExcExtUpDeDeO()/Case>以减少数据库和应用程序之间的往返行程总量,它应该在性能方面已经有了很大的帮助,特别是对于远程数据库,也许你甚至不需要用这种方法来使用多个线程了。李>
  • 我认为分享你的
    CallableStatement
    不是一个好的做法。我不认为它是线程安全的,您应该为每个线程使用专用的
    连接
    CallableStatement
  • 您需要调用
    connection.setAutoCommit(false)
    以禁用自动提交模式,该模式不用于加载大量数据。这意味着您需要显式地调用
    connection.commit()
    everyx存储记录
  • 在代码中,您应该使用
    Runnable
    而不是
    Thread
    ,因为这是
    ExecutorService
    所期望的。不需要在此处创建线程实例,因为
    ExecutorService
    会将其视为
    Runnable
    ,这样即使向
    ExecutorService
    执行
    提供了10个以上的
    Runnable
    对象,也只有10个线程
  • 不需要CountDownLatch,因为方法shutdown()已经涵盖了它,正如javadoc中提到的:
  • 启动有序关机,执行以前提交的任务,但不接受新任务


    实际上,我在代码中调用了一个存储过程,以便在处理记录后将员工详细信息插入到两个不同的表中。我已经用实际的代码编辑了我的文章。我的错误是,CallableStatement是一个PreparedStatement,所以你仍然可以调用addBatch而不是executeUpdate,但我必须承认我从未尝试过使用存储过程,所以你仍然应该尝试。@user3244519我的答案足够清楚吗?这对你有帮助吗?