当前位置:   article > 正文

java for循环内执行多线程_java for循环多线程

java for循环多线程

目录

一、java用多线程来加快循环效率(推荐第3种!!!!)

 第一种:线程池搭配闭锁

 第二种:分页概念执行线程

 第三种:分页概念执行线程进阶版!!!!


一、java用多线程来加快循环效率(推荐第3种!!!!

 第一种:线程池搭配闭锁

涉及知识:Executors(线程池)、CountDownLatch(闭锁)

优点:代码简洁,方便阅读,性能稳定;

缺点:Executors创建的线程池是公用的,如果多个地方使用这种循环多线程的方式,就会抢夺线程池资源,这样运行速度也会降低;

  1. import java.util.*;
  2. import java.util.concurrent.CountDownLatch;
  3. import java.util.concurrent.ExecutorService;
  4. import java.util.concurrent.Executors;
  5. public class test{
  6. public static void main(String[] args) throws Exception {
  7. /**
  8. * 两个要点:
  9. * 1.用Executors实现固定大小的线程池,从而达到控制硬件资源消耗的目的。
  10. * 2.用CountDownLatch(闭锁),来确保循环内的多线程都执行完成后,再执行后续代码
  11. */
  12. // 固定的线程池(当前线程池大小为5
  13. final ExecutorService executor = Executors.newFixedThreadPool(5);
  14. // 初始化数据
  15. List<Map<String,Object>> list = new ArrayList<>();
  16. for(int i=0;i<50;i++){
  17. Map<String,Object> object = new HashMap<>();
  18. object.put("index",i);
  19. list.add(object);
  20. }
  21. // 初始化计时器
  22. final CountDownLatch cdl = new CountDownLatch(list.size());
  23. System.out.println("====== 线程开始 =====");
  24. // 遍历
  25. for(final Map<String,Object> object:list){
  26. // 开启线程
  27. executor.submit(new Runnable() {
  28. @Override
  29. public void run() {
  30. try {
  31. Thread t = Thread.currentThread();
  32. String name = t.getName();
  33. // 模拟运行耗时
  34. Thread.sleep(500);
  35. System.out.println(name+":执行到"+object.get("index"));
  36. object.put("status","已经执行过");
  37. } catch (InterruptedException e) {
  38. e.printStackTrace();
  39. }
  40. // 闭锁-1
  41. cdl.countDown();
  42. }
  43. });
  44. }
  45. // 调用闭锁的await()方法,该线程会被挂起,它会等待直到count值为0才继续执行
  46. // 这样我们就能确保上面多线程都执行完了才走后续代码
  47. cdl.await();
  48. //关闭线程池
  49. executor.shutdown();
  50. System.out.println("====== 线程结束 =====");
  51. // 校验多线程正确性
  52. for(Map<String,Object> object:list){
  53. System.out.println(object.get("index") + ":" + object.get("status"));
  54. }
  55. }
  56. }

 第二种:分页概念执行线程

涉及知识:CountDownLatch(闭锁)

优点:运行速度快;

缺点:代码阅读难;

  1. public static void main(String[] args) throws InterruptedException {
  2. /**
  3. * 两个要点:
  4. * 1.设定线程数量,用分页的概念,将集合拆分成若干组分批执行线程
  5. * 2.用CountDownLatch(闭锁),来确保循环内的多线程都执行完成后,再执行后续代码
  6. */
  7. // 初始化数据
  8. final List<Map<String,Object>> list = new ArrayList<>();
  9. for(int i=0;i<6;i++){
  10. Map<String,Object> object = new HashMap<>();
  11. object.put("index",i);
  12. list.add(object);
  13. }
  14. int size = list.size(); //集合总数
  15. int theadCount = 5; // 执行线程数量
  16. int splitCount = size / theadCount + (size % theadCount != 0 ? 1 : 0); //计算分拆数量,向上取整
  17. final CountDownLatch cdl = new CountDownLatch(size); //计数器
  18. for (int i = 1; i <= theadCount; i++) {
  19. final int beign = (i - 1) * splitCount;
  20. final int end = (i * splitCount) > size ? size : i * splitCount;
  21. if(beign >= end) break;
  22. new Thread(new Runnable() {
  23. @Override
  24. public void run() {
  25. for (int j = beign; j < end; j++) {
  26. try {
  27. Thread t = Thread.currentThread();
  28. String name = t.getName();
  29. // 模拟运行耗时
  30. Thread.sleep(500);
  31. Map<String, Object> object = list.get(j);
  32. System.out.println(name+":执行到"+object.get("index"));
  33. object.put("status","已经执行过");
  34. } catch (InterruptedException e) {
  35. e.printStackTrace();
  36. }
  37. // 闭锁-1
  38. cdl.countDown();
  39. }
  40. }
  41. }).start();
  42. }
  43. // 调用闭锁的await()方法,该线程会被挂起,它会等待直到count值为0才继续执行
  44. // 这样我们就能确保上面多线程都执行完了才走后续代码
  45. cdl.await();
  46. System.out.println("====== 线程结束 =====");
  47. // 校验多线程正确性
  48. for(Map<String,Object> object:list){
  49. System.out.println(object.get("index") + ":" + object.get("status"));
  50. }
  51. }

 第三种:分页概念执行线程进阶版!!!!

涉及知识:CountDownLatch(闭锁)、对象封装;

优点:运行速度快,代码简洁优雅;

缺点:;

  1. package com.xxx;
  2. import java.util.ArrayList;
  3. import java.util.HashMap;
  4. import java.util.List;
  5. import java.util.Map;
  6. import java.util.concurrent.CountDownLatch;
  7. import java.util.concurrent.TimeUnit;
  8. /***
  9. * 多线程优化 by lyx 20230318
  10. * 在循环里跑多线程,提高执行速度
  11. */
  12. public class TheadMultis {
  13. private Integer theadCount; //线程数量
  14. private Integer size; //集合大小
  15. private Integer timeOut = 60; //超时时间(单位:分钟)
  16. private Function function; //执行方法
  17. public interface Function {
  18. void run(int i);
  19. }
  20. public TheadMultis(int theadCount, int size, Function function) {
  21. this.theadCount = theadCount;
  22. this.size = size;
  23. this.function = function;
  24. }
  25. public TheadMultis(int theadCount, int timeOut, int size, Function function) {
  26. this.theadCount = theadCount;
  27. this.timeOut = timeOut;
  28. this.size = size;
  29. this.function = function;
  30. }
  31. public void start() throws InterruptedException,TheadMultisException {
  32. int size = this.size; //集合总数
  33. int theadCount = this.theadCount; // 执行线程数量
  34. int splitCount = size / theadCount + (size % theadCount != 0 ? 1 : 0); //计算分拆数量,向上取整
  35. final CountDownLatch cdl = new CountDownLatch(size); //计数器
  36. for (int i = 1; i <= theadCount; i++) {
  37. final int beign = (i - 1) * splitCount;
  38. final int end = (i * splitCount) > size ? size : i * splitCount;
  39. if(beign >= end) break;
  40. new Thread(new Runnable() {
  41. @Override
  42. public void run() {
  43. for (int j = beign; j < end; j++) {
  44. try{
  45. function.run(j);
  46. }catch (Exception e){
  47. e.printStackTrace();
  48. }
  49. // 闭锁-1
  50. cdl.countDown();
  51. }
  52. }
  53. }).start();
  54. }
  55. int time = this.timeOut != null ? this.timeOut : 60;
  56. // 调用闭锁的await()方法,该线程会被挂起,它会等待直到count值为0才继续执行
  57. // 这样我们就能确保上面多线程都执行完了才走后续代码
  58. try{
  59. if(!cdl.await(time, TimeUnit.MINUTES)){
  60. throw new TheadMultisException("Executed for more than "+ time +" minutes");
  61. }
  62. }catch (InterruptedException e){
  63. throw e;
  64. }
  65. }
  66. public class TheadMultisException extends Exception{
  67. public TheadMultisException() {
  68. super();
  69. }
  70. public TheadMultisException(String s) {
  71. super(s);
  72. }
  73. }
  74. public static void main(String[] args) throws Exception {
  75. // 初始化数据
  76. final List<Map<String,Object>> list = new ArrayList<>();
  77. for(int i=0;i<10;i++){
  78. Map<String,Object> object = new HashMap<>();
  79. object.put("index",i);
  80. list.add(object);
  81. }
  82. new TheadMultis(2, 1,list.size(), new TheadMultis.Function() {
  83. @Override
  84. public void run(int i) {
  85. Thread t = Thread.currentThread();
  86. String name = t.getName();
  87. // 模拟运行耗时
  88. try {
  89. // Thread.sleep(1000 * 60);
  90. Thread.sleep(500);
  91. } catch (InterruptedException e) {
  92. e.printStackTrace();
  93. }
  94. Map<String, Object> object = list.get(i);
  95. System.out.println(name+":执行到"+object.get("index"));
  96. object.put("status","已经执行过");
  97. }
  98. }).start();
  99. System.out.println("====== 线程结束 =====");
  100. // 校验多线程正确性
  101. for(Map<String,Object> object:list){
  102. System.out.println(object.get("index") + ":" + object.get("status"));
  103. }
  104. }
  105. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/822751
推荐阅读
相关标签
  

闽ICP备14008679号