开发者

java for循环内执行多线程问题

开发者 https://www.devze.com 2023-03-10 10:34 出处:网络 作者: 熙街丶一人
目录Java用多线程来加快循环效率线程池搭配闭锁for循环中使用多线程总结java用多线程来加快循环效率
目录
  • Java用多线程来加快循环效率
    • 线程池搭配闭锁
  • for循环中使用多线程
    • 总结

      java用多线程来加快循环效率

      线程池搭配闭锁

      涉及知识:开发者_Python入门Executors(线程池)、CountDownLatch(闭锁)

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

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

      import java.util.*;
      import java.util.concurrent.CountDownLatch;
      import java.util.concurrent.ExecutorService;
      import java.util.concurrent.Executors;
       
      public class test{
       
          /** 固定的线程池(当前线程池大小为5) */
          private static final ExecutorService executor = Executors.newFixedThreadPool(5);
          
          public static void main(String[] args) throws Exception {
              /**
               *  两个要点:
               *  1.用Executors实现固定大小的线程池,从而达到控制硬件资源消耗的目的。
               *  2.用CountDownLatch(闭锁),来确保循环内的多线程都执行完成后,再执行后续代码
               */
              
              // 初始化数据
              List<Map<String,Object>> list = new ArrayList<http://www.devze.com>();
              for(int i=0;i<50;i++){
                  Map<String,Object> object = new HashMap<>();
                  object.put("index",i);
                  list.add(object);
              }
       
              // 初始化计时器
              CountDownLatch cdl = new CountDownLatch(list.size());
              System.out.println("====== 线程开始 =====");
       
              // 遍历
              for(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才继续执行
        javascript      // 这样我们就能确保上面多线程都执行完了才走后续代码
              cdl.await();
              
              //关闭线程池
              executor.shutdown();
              System.out.println("====== 线程结束 =python====");
       
              // 校验多线程正确性
              for(Map<String,Object> object:list){
                  System.out.println(object.get("index") + ":" + object.get("status"));
              }
       
          }
      }

      for循环中使用多线程

      每个service负责一个业务,多次进行重复业务就要使用到for循环,例如对某个存储id的集合遍历,并为每个id创建一些东西。

      但是使用单线程执行任务会因为等待上次任务执行完而浪费很多时间,并且一旦某次执行报错,任务就会停止执行,明显不符合我们的要求。

      这种情况就在for循环中使用多线程。

      import java.util.concurrent.LinkedBlojsckingQueue;
      import java.util.concurrent.ThreadPoolExecutor;
       
      public class Test {
       
          /**
           * ThreadPool 自定义一个线程池
           */
          private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(2, 4, 60L, TimeUnit.SECONDS, new LinkedblockingQueue<>(60000));
       
          public static void main(String[] args) {
              //自己的数组或集合,这里不再进行填充
              String[] ids js= new String[10]
              
              for (String id : ids) {
                  EXECUTOR.execute(new Runnable() {
                      @Override
                      public void run() {
                          try {
                              //需要执行的业务逻辑
                              System.out.println("业务逻辑正在执行");
                          } catch (Exception e) {
                              //todo
                          }
                      }
                  });
              }
          }
       
      }

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消