业务中用到大批量的报表数据需要导入数据库。使用原生jdbc虽然简单但是不满足后续的业务需求,这里使用多线程进行处理
service
/**
* Desc:
* 多线程插入数据
*
* @return
*/
void insertBatchThRead(List<BankRecord> priRecordList);
serviceImp
/**
* Desc:
* 批量插入数据
*
* @return
*/
@Override
public void insertBatchThRead(List<BankRecord> recordList) {
// 一个线程处理500条数据
int count = 500;
// 数据集合大小
int listSize = recordList.size();
// 开启的线程数
int runSize = (listSize / count) + 1;
// 存放每个线程的执行数据
List<BankRecord> newList = null;
// 创建一个线程池,数量和开启线程的数量一样
ExecutorService executor = Executors.newFixedThreadPool(runSize);
// 创建两个个计数器
CountDownLatch begin = new CountDownLatch(1);
CountDownLatch end = new CountDownLatch(runSize);
//开启的线程同时开始
begin.countDown();
for (int i = 0; i < runSize; i++) {
/* 计算每个线程执行的数据 */
if ((i + 1) == runSize) {
int startIdx = (i * count);
int endIdx = recordList.size();
newList = recordList.subList(startIdx, endIdx);
} else {
int startIdx = (i * count);
int endIdx = (i + 1) * count;
newList = recordList.subList(startIdx, endIdx);
}
BatchInsertBankRecordThread thread = new
BatchInsertBankRecordThread(newList, begin, end, bankRecordMapper);
executor.execute(thread);
}
try {
end.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.shutdown();
}
实现Runable 接口
public class BatchInsertBankRecordThread implements Runnable {
private BankRecordMapper BankRecordMapper;
/**
* 数据集合
*/
private List<BankRecord> list;
/**
* 每个线程处理的起始数据
*/
private CountDownLatch begin;
/**
* 每个线程处理的结束数据
*/
private CountDownLatch end;
public BatchInsertBankRecordThread(List<BankRecord> list,
CountDownLatch begin,
CountDownLatch end,
BankRecordMapper BankRecordMapper) {
this.list = list;
this.begin = begin;
this.end = end;
this.BankRecordMapper = BankRecordMapper;
}
@Override
public void run() {
try {
if (list != null && !list.isEmpty()) {
BankRecordMapper.insertBatch(list);
}
// 执行完让线程直接进入等待
begin.await();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 当一个线程执行完 了计数要减一不然这个线程会被一直挂起
end.countDown();
}
}
}
xml里面就是mybatis使用的foreach插入 这里不再赘述