耗时对比
t1: 耗时: 885739
t2: 耗时: 58548 | 耗时: 39284 | 耗时: 37096
t2_1: 耗时: 46900 | 耗时: 42319 | 耗时: 32841
t3: 耗时: 63848 | 耗时: 64668 | 耗时: 60082
t3_1: 耗时: 108355 | 耗时: 153665 | 耗时: 100006
/**
* 单线程
*/
@Operation(summary = "单线程")
@GetMapping("/t1")
public AjaxResult<?> t1(){
movieInformationUtil.main1();
return AjaxResult.success();
}
/**
* 多线程 使用切块分区使用多线程
*/
@Operation(summary = "多线程 使用切块分区使用多线程")
@GetMapping("/t2")
public AjaxResult<?> t2(){
movieInformationUtil.main2();
return AjaxResult.success();
}
/**
* 多线程 main2优化 使用批量插入
*/
@Operation(summary = "多线程 main2优化 使用批量插入")
@GetMapping("/t2_1")
public AjaxResult<?> t2_1(){
movieInformationUtil.main2_1();
return AjaxResult.success();
}
/**
* 多线程 可能会有遗漏 会有bug
*/
@Operation(summary = "多线程 可能会有遗漏 会有bug")
@GetMapping("/t3")
public AjaxResult<?> t3(){
movieInformationUtil.main3();
return AjaxResult.success();
}
/**
* 多线程 使用CountDownLatch等待全部线程执行完毕 解决main3遗漏问题
*/
@Operation(summary = "多线程 使用CountDownLatch等待全部线程执行完毕 解决main3遗漏问题")
@GetMapping("/t3_1")
public AjaxResult<?> t3_1(){
movieInformationUtil.main3_1();
return AjaxResult.success();
}
<!–多线程谷歌list分割–>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.0.0-jre</version>
</dependency>
package com.cn.crawlers.movieCrawler;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cn.domain.MovieInformation;
import com.cn.domain.MovieType;
import com.cn.service.MovieInformationService;
import com.cn.service.MovieTypeService;
import com.cn.utils.ImgUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 单线程
*/
public void main1() {
int[] i = {0};
long l1 = System.currentTimeMillis();
// 获取电影信息
QueryWrapper<MovieInformation> informationQueryWrapper = new QueryWrapper<>();
List<MovieInformation> movieList = movieInformationService.list(informationQueryWrapper);
for (MovieInformation item : movieList) {
//String base64 = ImgUtil.imageToBase64(imgUrl);
//item.setCoverUrlBase64(StringUtils.isBlank(base64) ? imgUrl : base64);
try {
Thread.sleep(10);
item.setCoverUrlBase64(String.valueOf(System.currentTimeMillis()));
movieInformationService.updateById(item);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
log.info("当前数量{},线程名称: {}", i[0]++, Thread.currentThread().getName());
}
long l2 = System.currentTimeMillis();
long l = l2 - l1;
System.out.println("耗时: " + l);
}
/**
* 多线程 使用切块分区使用多线程
*/
public void main2() {
int[] i = {0};
long l1 = System.currentTimeMillis();
// 获取电影信息
QueryWrapper<MovieInformation> informationQueryWrapper = new QueryWrapper<>();
List<MovieInformation> movieList = movieInformationService.list(informationQueryWrapper);
// 获取分区大小
List<List<MovieInformation>> partition = Lists.partition(movieList, movieList.size() / 20);
// 创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(partition.size());
CountDownLatch countDownLatch = new CountDownLatch(partition.size());
for (List<MovieInformation> items : partition) {
executorService.execute(new Runnable() {
@Override
public void run() {
for (MovieInformation item : items) {
String imgUrl = item.getCoverUrl();
try {
Thread.sleep(10);
item.setCoverUrlBase64(String.valueOf(System.currentTimeMillis()));
movieInformationService.updateById(item);
log.info("当前数量{},线程名称: {}", i[0]++, Thread.currentThread().getName());
} catch (Exception e) {
log.error("出bug了 -- {}", imgUrl);
}
}
countDownLatch.countDown();
}
});
}
// 等待所有的线程执行完毕
try {
countDownLatch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
// 关闭线程池
executorService.shutdown();
long l2 = System.currentTimeMillis();
long l = l2 - l1;
System.out.println("耗时: " + l);
}
/**
* 多线程 main2优化 使用批量插入
*/
public void main2_1() {
int[] i = {0};
long l1 = System.currentTimeMillis();
// 获取电影信息
QueryWrapper<MovieInformation> informationQueryWrapper = new QueryWrapper<>();
List<MovieInformation> movieList = movieInformationService.list(informationQueryWrapper);
// 获取分区大小
List<List<MovieInformation>> partition = Lists.partition(movieList, movieList.size() / 20);
// 创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(partition.size());
CountDownLatch countDownLatch = new CountDownLatch(partition.size());
for (List<MovieInformation> items : partition) {
executorService.execute(new Runnable() {
List<MovieInformation> addList = new ArrayList<>();
@Override
public void run() {
for (MovieInformation item : items) {
String imgUrl = item.getCoverUrl();
try {
Thread.sleep(10);
item.setCoverUrlBase64(String.valueOf(System.currentTimeMillis()));
addList.add(item);
log.info("当前数量{},线程名称: {}", i[0]++, Thread.currentThread().getName());
} catch (Exception e) {
log.error("出bug了 -- {}", imgUrl);
}
}
log.info("SQL更新了,更新数量{}", addList.size());
movieInformationService.updateBatchById(addList);
countDownLatch.countDown();
}
});
}
// 等待所有的线程执行完毕
try {
countDownLatch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
// 关闭线程池
executorService.shutdown();
long l2 = System.currentTimeMillis();
long l = l2 - l1;
System.out.println("耗时: " + l);
}
/**
* 多线程 可能会有遗漏 会有bug
*/
public void main3() {
int[] i = {0};
long l1 = System.currentTimeMillis();
// 获取电影信息
QueryWrapper<MovieInformation> informationQueryWrapper = new QueryWrapper<>();
List<MovieInformation> movieList = movieInformationService.list(informationQueryWrapper);
// 创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(20);
List<Future<MovieInformation>> futures = new ArrayList<>();
try {
// 提交所有任务,并获取所有任务的执行结果
for (MovieInformation item : movieList) {
Future<MovieInformation> submit = executorService.submit(() -> {
Thread.sleep(10);
item.setCoverUrlBase64(String.valueOf(System.currentTimeMillis()));
log.info("当前数量{},线程名称: {}", i[0]++, Thread.currentThread().getName());
return item;
});
futures.add(submit);
}
for (Future<MovieInformation> future : futures) {
MovieInformation movieInformation = future.get();
movieInformationService.updateById(movieInformation);
}
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
// 关闭线程池
executorService.shutdown();
long l2 = System.currentTimeMillis();
long l = l2 - l1;
System.out.println("耗时: " + l);
}
/**
* 多线程 使用CountDownLatch等待全部线程执行完毕 解决main3遗漏问题
*/
public void main3_1() {
int[] i = {0};
long l1 = System.currentTimeMillis();
// 获取电影信息
QueryWrapper<MovieInformation> informationQueryWrapper = new QueryWrapper<>();
List<MovieInformation> movieList = movieInformationService.list(informationQueryWrapper);
// 创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(20);
List<Future<MovieInformation>> futures = new ArrayList<>();
CountDownLatch countDownLatch = new CountDownLatch(movieList.size());
try {
// 提交所有任务,并获取所有任务的执行结果
for (MovieInformation item : movieList) {
Future<MovieInformation> submit = executorService.submit(() -> {
Thread.sleep(10);
item.setCoverUrlBase64(String.valueOf(System.currentTimeMillis()));
countDownLatch.countDown();
log.info("当前数量{},线程名称: {}", i[0]++, Thread.currentThread().getName());
return item;
});
futures.add(submit);
}
// 等待所有的线程执行完毕
try {
countDownLatch.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
for (Future<MovieInformation> future : futures) {
MovieInformation movieInformation = future.get();
movieInformationService.updateById(movieInformation);
}
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
// 关闭线程池
executorService.shutdown();
long l2 = System.currentTimeMillis();
long l = l2 - l1;
System.out.println("耗时: " + l);
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/192747.html