精华内容
下载资源
问答
  • 多并发下多线程遍历list问题

    千次阅读 2021-02-26 18:50:48
    今天做导出 查出的数据有3万条 还要遍历做一些处理 结果就超时想到多线程遍历list 去网上查找 找到这块代码:public String list2Str(List list, final int nThreads) throws Exception {if (list == null || list....

    今天做导出 查出的数据有3万条 还要遍历做一些处理 结果就超时

    想到多线程遍历list 去网上查找 找到这块代码:

    public String list2Str(List list, final int nThreads) throws Exception {

    if (list == null || list.isEmpty()) {

    return null;

    }

    StringBuffer ret = new StringBuffer();

    int size = list.size();

    ExecutorService executorService = Executors.newFixedThreadPool(nThreads);

    List> futures = new ArrayList>(nThreads);

    for (int i = 0; i < nThreads; i++) {

    final List subList = list.subList(size / nThreads * i, size / nThreads * (i + 1));

    Callable task = new Callable() {

    @Override

    public String call() throws Exception {

    StringBuffer sb = new StringBuffer();

    for (String str : subList) {

    sb.append(str);

    }

    return sb.toString();

    }

    };

    futures.add(executorService.submit(task));

    }

    for (Future future : futures) {

    ret.append(future.get());

    }

    executorService.shutdown();

    return ret.toString();

    }

    }

    我调用时开了5个线程 我想问 每次导出就开启5个线程 如果多个人同时导出 比如10000个人同时导出 那岂不是就开启了50000个线程了!!!

    没问题吗???

    展开全文
  • 开发过程中经常遇到如下需求,拿到一个list数据,需要遍历它然后请求第三方接口,然后根据返回结果做一些事 常规写法 public static void main(String[] args) { List<User> list = getList(); test1(list);...

    开发过程中经常遇到如下需求,拿到一个list数据,需要遍历它然后请求第三方接口,然后根据返回结果做一些事

    常规写法

    public static void main(String[] args) {
        List<User> list = getList();
        test1(list);
    }
    
    //假设有500条数据
    static List<User> getList() {
        List<User> list = new ArrayList<>();
        for (int i = 1; i < 501; i++) {
            User user = new User();
            user.setIdCard(i + "");
            list.add(user);
        }
        return list;
    }
    
    //常规的单线程处理方法
    static void test1(List<User> list) {
        long start = System.currentTimeMillis();
        for (User user : list) {
            sendRequest(user);
        }
        long end = System.currentTimeMillis();
        System.out.println("单线程方法,耗时:" + (end - start) + "ms");
    }
    
    //模拟请求第三方接口:根据身份证号获取姓名
    static void sendRequest(User user){
        //模拟接口请求耗时
        try {
            Thread.sleep(10);
        } catch (Exception e){}
        //模拟获取请求结果后做的一些事
        user.setName("张三-" + user.getIdCard());
        System.out.println("=====> 发送请求: name=" + user.getName());
    }
    
    @Data
    class User {
        private String idCard;
        private String name;
    }
    

    我们使用模拟数据造了 500 条数据,然后for循环列表去请求第三方接口获取数据,总共耗时大约为10 * 500 = 5000ms 以上
    在这里插入图片描述
    使用多线程改造后:

    public static void main(String[] args) {
        List<User> list = getList();
        test2(list);
    }
    
    //......省略getList(),上面有
    
    //多线程处理
    static void test2(List<User> list) {
        long start = System.currentTimeMillis();
        ExecutorService executor = Executors.newFixedThreadPool(10);
        final CountDownLatch countDownLatch = new CountDownLatch(list.size());
        for (User user : list) {
            executor.execute(new Task(user, countDownLatch));
        }
        try {
            countDownLatch.await();
        } catch (Exception e) {
    
        } finally {
            executor.shutdown();
        }
        long end = System.currentTimeMillis();
        System.out.println("多线程方法,耗时:" + (end - start) + "ms");
    }
    
    //实现Runnable的多线程类
    static class Task implements  Runnable {
    
            private User user;
            private CountDownLatch countDownLatch;
    
            public Task(User user, CountDownLatch countDownLatch) {
                this.user = user;
                this.countDownLatch = countDownLatch;
            }
    
            @Override
            public void run() {
                try {
                    sendRequest(user);
                } catch (Exception e) {
    
                } finally {
                    countDownLatch.countDown();
                }
            }
        }
    

    结果:
    在这里插入图片描述
    注意事项:

    1. 正常情况下,我们需要等多线程处理完,获取list数据,再去做一些业务操作(如入库,导出数据等),如果不需要等待结果,可以去掉countDownLatch,速度会更快
    2. Taskrun方法最好使用try...catch...finally,保证无论sendRequest()方法执行成功与否,countDownLatch都能减1,防止多线程无法终止

    完整Demo

    public class ForThreadTest {
    
        public static void main(String[] args) {
            List<User> list = getList();
            test1(list);
            test2(list);
        }
    
        //常规的单线程处理方法
        static void test1(List<User> list) {
            long start = System.currentTimeMillis();
            for (User user : list) {
                sendRequest(user);
            }
            long end = System.currentTimeMillis();
            System.out.println("单线程方法,耗时:" + (end - start) + "ms");
        }
    
        //多线程
        static void test2(List<User> list) {
            long start = System.currentTimeMillis();
            ExecutorService executor = Executors.newFixedThreadPool(10);
            final CountDownLatch countDownLatch = new CountDownLatch(list.size());
            for (User user : list) {
                executor.execute(new Task(user, countDownLatch));
            }
            try {
                countDownLatch.await();
            } catch (Exception e) {
        
            } finally {
                executor.shutdown();
            }
            long end = System.currentTimeMillis();
            System.out.println("多线程方法,耗时:" + (end - start) + "ms");
        }
    
    
        //假设有500条数据
        static List<User> getList() {
            List<User> list = new ArrayList<>();
            for (int i = 1; i < 501; i++) {
                User user = new User();
                user.setIdCard(i + "");
                list.add(user);
            }
            return list;
        }
    
        //模拟请求第三方接口:根据身份证号获取姓名
        static void sendRequest(User user){
            //模拟接口请求耗时
            try {
                Thread.sleep(10);
            } catch (Exception e){}
            //模拟获取请求结果后做的一些事
            user.setName("张三-" + user.getIdCard());
            System.out.println("=====> 发送请求: name=" + user.getName());
        }
    
        static class Task implements  Runnable {
    
            private User user;
            private CountDownLatch countDownLatch;
    
            public Task(User user, CountDownLatch countDownLatch) {
                this.user = user;
                this.countDownLatch = countDownLatch;
            }
    
            @Override
            public void run() {
                try {
                    sendRequest(user);
                } catch (Exception e) {
    
                } finally {
                    countDownLatch.countDown();
                }
            }
        }
    }
    
    @Data
    class User {
        private String idCard;
        private String name;
    }
    
    展开全文
  • import java.util....import java.util.List;import static java.lang.Thread.sleep;public class Test3 {public static void main(String[] args) throws Exception {long start = System.currentTimeMillis...

    import java.util.ArrayList;

    import java.util.List;

    import static java.lang.Thread.sleep;

    public class Test3 {

    public static void main(String[] args) throws Exception {

    long start = System.currentTimeMillis();

    List list = new ArrayList<>(1000);

    int count = 0 ;

    for (int i = 0; i < 1000; i++) {

    list.add("a_"+count);

    count++;

    }

    // list.parallelStream().forEach(item -> {

    list.parallelStream().forEachOrdered(item -> {

    try {

    sleep(1);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    System.out.println("item = " + item);

    });

    /*for (int i = 0; i

    sleep(1);

    System.out.println("item = " + list.get(i));

    }*/

    long end = System.currentTimeMillis();

    System.out.println("总时间 = " + (end - start));

    }

    }

    展开全文
  • Springboot自定义线程池,多线程遍历list及有返回值 自定义连接池 /** * @description: 某功能公共线程池 * @author: zjq * @create: 2021-01-06 15:35 **/ @Configuration public class ...

    Springboot自定义线程池,多线程遍历list及有返回值

    自定义连接池

    /**
     * @description: 某功能公共线程池
     * @author: zjq
     * @create: 2021-01-06 15:35
     **/
    @Configuration
    public class TranslationThreadPoolConfig {
        // 核心线程池大小
        private int corePoolSize = 20;
    
        // 最大可创建的线程数
        private int maxPoolSize = 50;
    
        // 队列最大长度
        private int queueCapacity = 1000;
    
        // 线程池维护线程所允许的空闲时间
        private int keepAliveSeconds = 300;
    
        //线程名称前缀
        private String threadNamePrefix="线程名称前缀";
    
        @Primary
        @Bean(name = "translationThreadPoolTaskExecutor")
        public ThreadPoolTaskExecutor translationThreadPoolTaskExecutor()
        {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setMaxPoolSize(maxPoolSize);
            executor.setCorePoolSize(corePoolSize);
            executor.setQueueCapacity(queueCapacity);
            executor.setKeepAliveSeconds(keepAliveSeconds);
            executor.setThreadNamePrefix(threadNamePrefix);
            // 线程池对拒绝任务(无线程可用)的处理策略
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            return executor;
        }
    }
    

    service层调用

    1.serviceImpl其他代码忽略

    2.依赖注入自定义线程池对象

       @Autowired
       @Qualifier("translationThreadPoolTaskExecutor")
       private Executor executor;
    

    3.方法调用

    //需要多线程遍历的list
    List<Map<String, Object>> waitSortBizDatas =new ArrayList(Map<String, Object>);
    //多线程执行行转译
    List<CompletableFuture<RuleResult>> collect = waitSortBizDatas.stream().map(waitSortBizData -> CompletableFuture.supplyAsync(() ->                                 
            //调用别的方法
            iAccRuleService.ruleExecute(voucherLineId, ruleIds,bizTable.getTableCode(), waitSortBizData), executor)
            ).collect(Collectors.toList());
    //获取返回值
    List<RuleResult> list = collect.stream().map(CompletableFuture::join).collect(Collectors.toList());
    
    展开全文
  • 遍历List的多种方式在讲如何线程安全地遍历List之前,先看看通常我们遍历一个List会采用哪些方式。方式一:for(int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}方式二:Iterator iterator ...
  • list> #include <mutex> using namespace std; class FindFile { public: FindFile() {} ~FindFile(); //搜索目录下所有文件 void doSearch(const std::string strDir); private: std::mutex m_mx...
  • if (directory == null) { //10ms内还未遍历到新的目录,则认为遍历完毕 if (System.currentTimeMillis() - stamp >= 10) { System.out.println("文件数:" + this.files.size() + "(" + (System.currentTimeMillis...
  • 多线程遍历集合数据

    2021-06-14 00:38:07
    import java.util.List; public class ThreadForeach { public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); for(int i=0;i<666;i++) { list.add(i)...
  • 多线程下使用Iterator来迭代对象时,总会包ConcurrentModificationException();异常,经过我对list和Iterator相关源码的分析,终于搞明白了这个问题:下面结合源代码来讨论这个问题:1、当我们调用一个List的...
  • 复习IO操作,突然想写一个小工具,统计一下电脑里面的Java代码量还有注释率,最开始随手写了一个递归算法,遍历文件夹,比较简单,而且代码层次清晰,相对易于理解,代码如下:(完整代码贴在最后面,前面是功能实现...
  • } } } So when two threads operate on the list, one thread can either add a single element or iterate over the entire list at a time. You have no parallel execution on these parts of the code. ...
  • 目录应用目标思路分析1.扫描网段2.远程建立FTP连接3....输入起始和终止IP地址,每个IP地址分别对应一个线程。 def main(): fir = input('输入扫描网段的ip起始地址:') end = input('输入扫描网段
  • 展开全部importjava.util.List;importjava.util.concurrent.Callable;importjava.util.concurrent.ExecutionException;importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;importj.....
  • 在单线程操作List,Dictionary等集合的时候一点问题都没有,但是在多线程情况下,问题就出来了,经常会报错。我们可以看看源码,List的Add方法是线程不安全的,List的源码中的Add方法,使用了每次当当前的元素达到...
  • 一、Java8之前遍历List方式 1. Iterator迭代器 Iterator<String> iterator = codeList.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } 2. for循环 for (int i = 0; i <...
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼这篇文章诺博源介绍了JAVA读取文件夹大小的单线程递归方式实例,有需要的朋友可以参考一下。具体的诺博源分享如下:package com.taobao.test;import java.io.File;public...
  • 我们在日常写代码的过程中,经常会使用多线程提高效率,我们在使用多线程过程中难免会出现往List集合修改数据。 下面我们来尝试一下往ArrayList 添加数据: public static void main(String[] args) { List<...
  • Java遍历List数组

    2021-06-02 19:36:49
    Java如何遍历List数组 1.增强for循环 for(String str : list) {//其内部实质上还是调用了... i++) {//内部不锁定,效率最高,但在多线程要考虑并发操作的问题。 System.out.println(list.get(i)); } 3.迭代器遍历 It
  • 多线程下 ArrayList 出现null的问题 发现这个问题 在某个项目中使用了ArrayList 了,将他带入到 子线程中去添加待定值,然后出现了意向不到的错误,报空指针异常,出现一个 null 值,而且该问题不必现,有时候经常跑代码才...
  • 多线程数量的问题,一般情况下,多线程数量要等于机器CPU核数-1。 二、实例 1、解决问题:如何让n个线程顺序遍历含有n个元素的List集合 import java.util.ArrayList; import java.util.List; import org.apache....
  • 转自:https://blog.csdn.net/changjizhi1212/article/details/81036509JAVA中循环遍历list有三种方式for循环、增强...1、for循环遍历listfor(int i=;iif(list.get(i).equals("del"))list.remove(i);}这种方式的问...
  • Java中List集合的遍历

    2021-02-12 13:58:18
    一、对List遍历有三种方式List list = new ArrayList();list.add("testone");list.add(“testtwo”);...第一种:for(Iterator it = list.iterator(); it.hasNext(); ) {....}这种方式在循环执行过程中会进行数据...
  • 针对此问题,查阅了网上很多资料,好多都使用多线程来处理。跟着好多的博客进行处理,要么是线程安全问题,要么根本速度就提高不了。我针对我项目中的使用场景,结合资料进行了修改,特提交此文,为有共同需求的小...
  • 一、对List遍历有三种方式List list = new ArrayList();list.add("testone");list.add(“testtwo”);...第一种:for(Iterator it = list.iterator(); it.hasNext(); ) {....}这种方式在循环执行过程中会进行数据...
  • public ExecupteHp (List list){this.list =list ; } @Overridepublic voidrun() {if(null!=list){for(SidCustPersonContactInfo scpc : list){ System.out.print("更新会员联系方式" +scpc.getFirstName() + "---"+...
  • java 多线程 出现数据重复调用问题线程操作过程描述:1、线程查询数据库表(table1)数据,并遍历修改记录状态(防止出现数据重复调用)。(此操作加入了同步锁)2、调用接口,获取返回的状态。3、把数据插入到数据库...
  • 1、目标:输出类似 Windows 的命令行工具中 tree /F 命令所得到的目录树: 2、语言、算法: 所使用的计算机语言:Java 涉及算法:递归算法 ...分别使用单线程、多线程实现此功能; 在线程开始时和线...
  • Java List遍历的3种方法

    千次阅读 2021-03-07 10:28:39
    Java List遍历的3种方法1.Iterator遍历list集合List list=new ArrayList();list.add("java1");list.add("java2");list.add("java3");for(Iteratorit = list.iterator(); it.hasNext(); ){....}这种方式在循环执行...
  • 记录该问题是因为当时需要list读取完该元素后,下次不再读取该元素值 使用ListIterator()方法,代码如下: List list = new ArrayList(); list.add("a"); list.add("b"); list.add("c"); list.add("d"); ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 144,465
精华内容 57,786
关键字:

多线程遍历list存在问题

友情链接: quartJob.zip