使用多线程及线程池批量拷贝数据到MongoDB
@
提示:本文仅供学习交流,请勿用于非法活动!
前言
本文大概内容:
例如:随着MongoDB的广泛应用,电商用到MongoDB也越来越多。本文主要是在将购物车模块切换到MongoDB框架前,如何快速将Mysql中购物车大批量订单拷贝到MongoDB数据库中?
一、原来代码
如下,我们将拷贝100万条数据到MongoDB中。
public void copyCartToMongo() {
List<Cart> carts = cartMapper.selectAll();
if(carts.size() >0 ){
cartMongoService.saveCartList(carts);
}
}
二、改进后代码
public void copyCartToMongoByThread() {
// 1.我们先将批量查询及拷贝的数据分批
EntityWrapper<Cart> wrapper = SQLHelper.buildEmptyWrapper(Cart.class);
long count = cartMapper.selectCount(SQLHelper.build(Cart.class).geEntityWrapper());
int preCount = 100;
int operateCount = 0;
int num = operateCount = (int)count / preCount;
if(count % preCount == 0){
operateCount = num;
}else {
operateCount = num + 1;
}
for(int i=0;i<operateCount;i++){
logger.info("保存或更新第"+(i+1)*preCount+"条数据");
Page<Cart> page = new Page<>(i,preCount);
List<Cart> cartList = cartMapper.selectPage(page, wrapper);
// 2.通过多线程、线程池(其他替换即可)
this.copyCartToMongoThread(cartList);
}
}
上述代码中有以下三种方式实现:
1.使用new Thread方式
代码如下:
public void copyCartToMongoThread(List<Cart> cartList){
final CountDownLatch latch = new CountDownLatch(cartList.size());
try{
for(Cart cart:cartList){
Thread thread = new Thread(() -> {
cartMongoService.saveCart(cart);
latch.countDown();
});
thread.start();
}
latch.await();
} catch (Exception e) {
e.printStackTrace();
}
}
2.使用Runnable接口
代码如下:
public void copyCartToMongoThread(List<Cart> cartList){
final CountDownLatch latch = new CountDownLatch(cartList.size());
try {
for (Cart cart:cartList){
new Thread(new Runnable() {
@Override
public void run() {
cartMongoService.saveCart(cart);
latch.countDown();
}
}).start();
}
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
3.使用线程池
代码如下:
public void copyCartToMongoThreadPool(List<Cart> cartList){
final CountDownLatch latch = new CountDownLatch(cartList.size());
// 配置线程池个数
ExecutorService executorService = Executors.newFixedThreadPool(1);
try{
for(Cart cart:cartList){
executorService.submit(new Runnable() {
@Override
public void run() {
try{
cartMongoService.saveCart(cart);
// 一直阻塞当前线程,直到计数器值为0,保证并发
latch.await();
} catch (Exception e) {
e.printStackTrace();
}
}
});
latch.countDown();
}
} catch (Exception e) {
e.printStackTrace();
}
}
随心所往,看见未来。Follow your heart,see night!
欢迎点赞、关注、留言,一起学习、交流!