我正在尝试将数百万个数据行插入数据库。我正在尝试使用ThreadPoolExecutor来实现此目的。我正在为每9000条记录创建一个批处理并将批处理发送到每个线程。在这里,我将ThreadPool Size修改为20.大小增加后,它会失败。如何检查ThreadPoolExecutor中可用的线程数以及如何等待线程池有空闲线程。
听到我的代码,如果我错了,请帮忙。
int threadCount=10;
ThreadPoolExecutor threadPool = (ThreadPoolExecutor) Executors.newFixedThreadPool(threadCount);
int i=0;
StringBuffer sb=new StringBuffer();
sb.append("BEGIN BATCH");
sb.append(System.lineSeparator());
int cnt =metaData.getColumnCount();
while(rs.next())
{
String query ="INSERT INTO "+table+" ("+columnslist.get(1)+")VALUES("+i;
for ( int j=1 ; j <= cnt ; j++)
{
if(metaData.getColumnTypeName(j).contains("int") || metaData.getColumnTypeName(j).contains("number"))
{
query +=","+ rs.getInt(j);
}
else if(metaData.getColumnTypeName(j).contains("varchar") || metaData.getColumnTypeName(j).contains("date") || metaData.getColumnTypeName(j).contains("getTimestamp"))
{
query +=",'"+parseColumnData(rs.getString(j))+"'";
}
else
{
query +=",'"+parseColumnData(rs.getString(j))+"'";
}
}
query +=");";
sb.append(query);sb.append(System.lineSeparator());
if(i%9000==0)
{
sb.append("APPLY BATCH");
System.out.println(threadPool.getActiveCount());
Thread t = new Thread(new ExcecuteTask(sb.toString(),session));
threadPool.execute(t);
sb.setLength(0);
sb.append("BEGIN BATCH");
sb.append(System.lineSeparator());
}
i++;
}
sb.append("APPLY BATCH");
Thread t = new Thread(new ExcecuteTask(sb.toString(),session));
threadPool.execute(t);
sb.setLength(0);
threadPool.shutdown();
while (threadPool.getTaskCount() != threadPool.getCompletedTaskCount())
{
}
System.out.println(table+" Loaded sucessfully");
public class ExcecuteTask implements Runnable
{
private String sb;
private Session session;
public ExcecuteTask(String s,Session session)
{
sb = s;
this.session=session;
}
public void run()
{
session.executeAsync(sb.toString());
}
}
答案 0 :(得分:1)
您可以通过调用ThreadPoolExecutor
方法在getActiveCount
中找到活动线程的大致数量。但是你不应该这样做。
来自Java documentation for Executors.newFixedThreadPool
创建一个线程池,该线程池重用在共享无界队列中运行的固定数量的线程。在任何时候,最多nThreads线程将是活动的处理任务。如果在所有线程都处于活动状态时提交了其他任务,则它们将在队列中等待,直到线程可用。如果任何线程由于在关闭之前执行期间的故障而终止,则在需要执行后续任务时将使用新的线程。池中的线程将一直存在,直到明确关闭为止。
因此,您应该能够继续向线程池提交任务,并且当线程可用时,它们将被选中并运行。
我还注意到,您将任务包装在Thread
个对象中,然后再将它们提交给线程池,这是不必要的。