Java 使用CountDownLatch和ExecutorService类在DB中插入100K条记录
我必须从一个有超过100K条记录的ArrayList中插入一些DB值。我使用下面给出的CountDownLatch和ExecutorService类一次运行10个线程,以提高插入时的性能。我正在调用一个存储过程,在对详细信息进行一些处理之后,将员工详细信息插入到两个不同的表中。这是否符合我的要求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
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个线程
实际上,我在代码中调用了一个存储过程,以便在处理记录后将员工详细信息插入到两个不同的表中。我已经用实际的代码编辑了我的文章。我的错误是,CallableStatement是一个PreparedStatement,所以你仍然可以调用addBatch而不是executeUpdate,但我必须承认我从未尝试过使用存储过程,所以你仍然应该尝试。@user3244519我的答案足够清楚吗?这对你有帮助吗?