赞
踩
目录
涉及知识:Executors(线程池)、CountDownLatch(闭锁)
优点:代码简洁,方便阅读,性能稳定;
缺点:Executors创建的线程池是公用的,如果多个地方使用这种循环多线程的方式,就会抢夺线程池资源,这样运行速度也会降低;
- import java.util.*;
- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
-
- public class test{
-
- public static void main(String[] args) throws Exception {
-
- /**
- * 两个要点:
- * 1.用Executors实现固定大小的线程池,从而达到控制硬件资源消耗的目的。
- * 2.用CountDownLatch(闭锁),来确保循环内的多线程都执行完成后,再执行后续代码
- */
-
- // 固定的线程池(当前线程池大小为5
- final ExecutorService executor = Executors.newFixedThreadPool(5);
-
- // 初始化数据
- List<Map<String,Object>> list = new ArrayList<>();
- for(int i=0;i<50;i++){
- Map<String,Object> object = new HashMap<>();
- object.put("index",i);
- list.add(object);
- }
-
- // 初始化计时器
- final CountDownLatch cdl = new CountDownLatch(list.size());
- System.out.println("====== 线程开始 =====");
-
- // 遍历
- for(final Map<String,Object> object:list){
- // 开启线程
- executor.submit(new Runnable() {
- @Override
- public void run() {
- try {
- Thread t = Thread.currentThread();
- String name = t.getName();
- // 模拟运行耗时
- Thread.sleep(500);
- System.out.println(name+":执行到"+object.get("index"));
- object.put("status","已经执行过");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- // 闭锁-1
- cdl.countDown();
- }
- });
- }
-
- // 调用闭锁的await()方法,该线程会被挂起,它会等待直到count值为0才继续执行
- // 这样我们就能确保上面多线程都执行完了才走后续代码
- cdl.await();
-
-
- //关闭线程池
- executor.shutdown();
- System.out.println("====== 线程结束 =====");
-
- // 校验多线程正确性
- for(Map<String,Object> object:list){
- System.out.println(object.get("index") + ":" + object.get("status"));
- }
-
- }
- }
涉及知识:CountDownLatch(闭锁)
优点:运行速度快;
缺点:代码阅读难;
- public static void main(String[] args) throws InterruptedException {
- /**
- * 两个要点:
- * 1.设定线程数量,用分页的概念,将集合拆分成若干组分批执行线程
- * 2.用CountDownLatch(闭锁),来确保循环内的多线程都执行完成后,再执行后续代码
- */
-
- // 初始化数据
- final List<Map<String,Object>> list = new ArrayList<>();
- for(int i=0;i<6;i++){
- Map<String,Object> object = new HashMap<>();
- object.put("index",i);
- list.add(object);
- }
-
- int size = list.size(); //集合总数
- int theadCount = 5; // 执行线程数量
- int splitCount = size / theadCount + (size % theadCount != 0 ? 1 : 0); //计算分拆数量,向上取整
- final CountDownLatch cdl = new CountDownLatch(size); //计数器
-
- for (int i = 1; i <= theadCount; i++) {
- final int beign = (i - 1) * splitCount;
- final int end = (i * splitCount) > size ? size : i * splitCount;
- if(beign >= end) break;
-
- new Thread(new Runnable() {
- @Override
- public void run() {
- for (int j = beign; j < end; j++) {
- try {
- Thread t = Thread.currentThread();
- String name = t.getName();
- // 模拟运行耗时
- Thread.sleep(500);
- Map<String, Object> object = list.get(j);
- System.out.println(name+":执行到"+object.get("index"));
- object.put("status","已经执行过");
-
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- // 闭锁-1
- cdl.countDown();
- }
- }
- }).start();
- }
-
- // 调用闭锁的await()方法,该线程会被挂起,它会等待直到count值为0才继续执行
- // 这样我们就能确保上面多线程都执行完了才走后续代码
- cdl.await();
- System.out.println("====== 线程结束 =====");
- // 校验多线程正确性
- for(Map<String,Object> object:list){
- System.out.println(object.get("index") + ":" + object.get("status"));
- }
-
-
- }
涉及知识:CountDownLatch(闭锁)、对象封装;
优点:运行速度快,代码简洁优雅;
缺点:;
- package com.xxx;
-
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.concurrent.CountDownLatch;
- import java.util.concurrent.TimeUnit;
-
- /***
- * 多线程优化 by lyx 20230318
- * 在循环里跑多线程,提高执行速度
- */
- public class TheadMultis {
-
- private Integer theadCount; //线程数量
-
- private Integer size; //集合大小
-
- private Integer timeOut = 60; //超时时间(单位:分钟)
-
- private Function function; //执行方法
-
-
- public interface Function {
- void run(int i);
- }
-
- public TheadMultis(int theadCount, int size, Function function) {
- this.theadCount = theadCount;
- this.size = size;
- this.function = function;
- }
- public TheadMultis(int theadCount, int timeOut, int size, Function function) {
- this.theadCount = theadCount;
- this.timeOut = timeOut;
- this.size = size;
- this.function = function;
- }
-
- public void start() throws InterruptedException,TheadMultisException {
- int size = this.size; //集合总数
- int theadCount = this.theadCount; // 执行线程数量
- int splitCount = size / theadCount + (size % theadCount != 0 ? 1 : 0); //计算分拆数量,向上取整
- final CountDownLatch cdl = new CountDownLatch(size); //计数器
-
- for (int i = 1; i <= theadCount; i++) {
- final int beign = (i - 1) * splitCount;
- final int end = (i * splitCount) > size ? size : i * splitCount;
- if(beign >= end) break;
-
- new Thread(new Runnable() {
- @Override
- public void run() {
- for (int j = beign; j < end; j++) {
- try{
- function.run(j);
- }catch (Exception e){
- e.printStackTrace();
- }
- // 闭锁-1
- cdl.countDown();
- }
- }
- }).start();
- }
-
- int time = this.timeOut != null ? this.timeOut : 60;
- // 调用闭锁的await()方法,该线程会被挂起,它会等待直到count值为0才继续执行
- // 这样我们就能确保上面多线程都执行完了才走后续代码
- try{
- if(!cdl.await(time, TimeUnit.MINUTES)){
- throw new TheadMultisException("Executed for more than "+ time +" minutes");
- }
- }catch (InterruptedException e){
- throw e;
- }
- }
-
- public class TheadMultisException extends Exception{
-
- public TheadMultisException() {
- super();
- }
-
- public TheadMultisException(String s) {
- super(s);
- }
- }
-
- public static void main(String[] args) throws Exception {
- // 初始化数据
- final List<Map<String,Object>> list = new ArrayList<>();
- for(int i=0;i<10;i++){
- Map<String,Object> object = new HashMap<>();
- object.put("index",i);
- list.add(object);
- }
-
- new TheadMultis(2, 1,list.size(), new TheadMultis.Function() {
- @Override
- public void run(int i) {
- Thread t = Thread.currentThread();
- String name = t.getName();
- // 模拟运行耗时
- try {
- // Thread.sleep(1000 * 60);
- Thread.sleep(500);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- Map<String, Object> object = list.get(i);
- System.out.println(name+":执行到"+object.get("index"));
- object.put("status","已经执行过");
- }
- }).start();
-
- System.out.println("====== 线程结束 =====");
- // 校验多线程正确性
- for(Map<String,Object> object:list){
- System.out.println(object.get("index") + ":" + object.get("status"));
- }
-
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。