java.util.concurrent多线程并行处理返回处理结果(计算一个list集合)

java.util.concurrent多线程并行处理返回处理结果(计算一个list集合)

普通情况下,我们使用Runnable作为主要的任务表示形式,可是Runnable是一种有非常大局限的抽象,run方法中仅仅能记录日志,打印,或者把数据汇总入某个容器(一方面内存消耗大,还有一方面须要控制同步,效率非常大的限制),总之不能返回运行的结果;
比方同一时候1000个任务去网络上抓取数据,然后将抓取到的数据进行处理(处理方式不定),
最好的方式就是提供回调接口,把处理的方式最为回调传进去;
可是如今我们有了更好的方式实现:CompletionService + Callable
CompletionService将Executor(线程池)和BlockingQueue(堵塞队列)结合在一起,同一时候使用Callable作为任务的基本单元,整个过程就是生产者不断把Callable任务放入堵塞对了,Executor作为消费者不断把任务取出来运行,并返回结果;
优势:
a、堵塞队列防止了内存中排队等待的任务过多,造成内存溢出(毕竟一般生产者速度比較快,比方爬虫准备好网址和规则,就去运行了,运行起来(消费者)还是比較慢的)
b、CompletionService能够实现,哪个任务先运行完毕就返回,而不是按顺序返回,这样能够极大的提升效率

以下代码实现list集合分发多线程串行计算返回计算结果

package com.project.service.service.impl;
import com.google.common.collect.Lists;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
import java.util.concurrent.*;
public class Test {


    /**
     * 多线程并发遍历list源数据
     * 将每个线程处理结果返回
     * @param args
     * @throws Exception
     */
    public static void main (String[]args) throws Exception{
        //创建操作源数据 list集合
        List list = Lists.newArrayList();
        for(int i =1;i<=21;i++){
            Student student=new Student(i,"test-"+i);
            list.add(student);
        }
        //创建线程池
        ExecutorService exec = Executors.newFixedThreadPool(10);
        CompletionService<List<Student>> cpiService =new ExecutorCompletionService<>(exec);
        int f=0;
        int i =0 ;

        //分发线程
        while (true){
            f=f+1;
            int g=(i+10)>list.size()?(list.size()):(i+10);

           testCallable callable=new testCallable(f,list.subList(i,g));
            if(!exec.isShutdown()){
                cpiService.submit(callable);
            }
            i=(g);
            if(i>=(list.size()))
                break;
        }
        System.out.println("f:"+f+";i:"+i+";size:"+list.size());
        //获取线程处理结果
        for(int h=0;h<f;h++){
            List<Student> students=cpiService.take().get();
            for(Student student:students){
                System.out.println("result-"+h+"-["+student+"]");
            }
        }
        //关闭多线程池
        exec.shutdown();
    }
    @Getter
    @Setter
    static class Student {
        private int id ;
        private String name ;

        public Student(int id, String name) {
            this.id = id;
            this.name = name;
        }

        public Student() {
        }

        @Override
        public String toString() {
            return id+"-student{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

    //创建多线程处理类
    static class testCallable implements Callable<List<Student>>{
        private int flag;
        private List<Student> students;

        public testCallable(int flag, List<Student> students) {
            this.flag = flag;
            this.students = students;
        }

        public testCallable() {
        }

        @Override
        public List<Student> call() throws Exception {
            students.stream().forEach(e->printStudent(flag,e));
            return students;
        }

        public void printStudent(int i,Student student ){
            System.out.println("call-"+i+"-["+student+"]");
        }
    }
}

你可能感兴趣的:(java,并发编程,多线程,并发计算)