スレッド プール ThreadPool を使用して、このプロジェクトでマルチスレッドのビデオ ダウンロードとシングルスレッドのビデオ ダウンロードをシミュレートするための時間消費など、効率を改善します。
以前、Douyin 動画のダウンロードについて書きましたが、検索する動画が毎回異なるため、ダウンロードする動画のサイズも一貫していないため、マルチスレッドとシングルスレッドの効率を比較する方法がないため、今回はダウンロード メソッド、現在のスレッドの方法をスリープ状態にして、ビデオのダウンロードをシミュレートします。
スレッド プール オブジェクトを作成します。
/**
* @Author itmei
* @Date 2023/3/16
* @description: 线程池对象
* @Title: ThreadPoolConfig
* @Package com.itmei.threadpool.config
*/
@Configuration
public class ThreadPoolConfig {
/**
* 核心池大小
*/
private final int corePoolSize = 50;
/**
* 最大创建线程数
*/
private final int maxPoolSize =100;
/**
* 线程池维护线程允许的空闲时间 (默认60秒)
*/
private final int keepAliveSeconds = 300;
/**
* 队列最大长度
*/
private final int queueCapacity = 1000;
@Bean(name = "threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
ThreadPoolTaskExecutor taskExecutor=new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(corePoolSize);
taskExecutor.setMaxPoolSize(maxPoolSize);
taskExecutor.setKeepAliveSeconds(keepAliveSeconds);
taskExecutor.setQueueCapacity(queueCapacity);
// 线程池对拒绝任务(无线程可用)的处理策略
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return taskExecutor;
}
}
シミュレーションのダウンロード:
@Service
public class VideoService implements ApplicationRunner {
@Resource
private ThreadPoolTaskExecutor taskExecutor;
private final Logger log = LoggerFactory.getLogger(VideoService.class);
/**
* 是否开启多线程
*/
private boolean threadFlag = true;
@Override
public void run(ApplicationArguments args) throws Exception {
init();
}
public void download(){
try {
//模拟睡眠10秒,比作下载视频所需要的时间
log.info("线程{}开始下载",Thread.currentThread().getName());
Thread.sleep(10*1000);
log.info("线程{}下载完成",Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void init(){
//模拟下载5个视频
int videos = 5;
long startTime = System.currentTimeMillis();
log.info("》》》开始下载视频《《《");
for (int i = 0; i < videos; i++) {
if (threadFlag){
taskExecutor.execute(() -> {
//线程任务
download();
});
}else {
download();
}
}
//需要等待子线程完成后再走主线程
while (threadFlag){
try {
int activeCount = taskExecutor.getActiveCount();
if (activeCount == 0) {
break;
}
//让主线程等待个1秒减少while的次数
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
log.info("总耗时:{} 秒!",(endTime-startTime)/1000);
}
}
実行結果:
マルチスレッド操作
シングルスレッド
次の効果から、単一のスレッドの効率は実行中のメイン スレッドが 1 つだけであることがわかります。