线程池优化for循环

线程池优化for循环

列子


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * 循环里面使用线程池执行里面东西
 */
public class Test1 {

    public static ThreadPoolExecutor threadPoolExecutor;

    public static List list1;

    public static void main(String[] args) {

        //创建线程池 普通的
        threadPoolExecutor = new ThreadPoolExecutor(128, 128, 0, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(Integer.MAX_VALUE));

        List list = new ArrayList<>();
        list.add("0");
        list.add("1");
        list.add("2");
        list.add("3");
        list.add("4");
        list.add("5");
        list.add("6");
        list.add("7");
        list.add("8");
        list.add("9");
        long l = System.currentTimeMillis();
        m1(list);
        long l1 = System.currentTimeMillis();
        System.out.println("耗时:" + (l1- l) + "ms");
        System.out.println(list1);
    }

    //没使用线程池处理
    public static void m1(List list) {
        List objects = new ArrayList<>();
        list.stream().forEach(item -> {
            try {
                new Thread().sleep(1000);//模拟执行延迟
                System.out.println("[0]" + Thread.currentThread().getName()+"----"+item);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            objects.add(item + "A");//stream内部访问不了list1
            System.out.println(objects);
        });
        list1 = objects;
        System.out.println("stream");
    }

    //线程没有顺序执行的,时间短
    public static void m2(List list) {
        for (String s : list) {
//            System.out.println(s);
            Runnable run = new Runnable() {
                public void run() {
                    try {
                        new Thread().sleep(1000);
                        //模拟耗时操作
                        System.out.println("[1]" + Thread.currentThread().getName()+"----"+s);
                        list1.add(s + "A");
                    } catch (Exception e) {
                    }
                }
            };
            threadPoolExecutor.execute(run);
        }

    }

    public static void m3(List list) {
         List objects = new ArrayList<>();
        list.stream().map(item -> {

            return threadPoolExecutor.submit(() -> {
                try {
                    new Thread().sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("[1]" + Thread.currentThread().getName()+"----"+item);
                synchronized (objects) {
                    objects.add(item + "A");
                }
            });
        }).forEach(future -> wait4Done(future));
        list1 = objects;

    }


    //等待执行完成,第一个线程执行完后,才会执行下一个线程任务
    public static void wait4Done(Future future) {
        try {
            if (future != null) {
                future.get();
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }


}

效果

  1. m1方法:正常循环执行
[0]main----0
[0A]
[0]main----1
[0A, 1A]
[0]main----2
[0A, 1A, 2A]
[0]main----3
[0A, 1A, 2A, 3A]
[0]main----4
[0A, 1A, 2A, 3A, 4A]
[0]main----5
[0A, 1A, 2A, 3A, 4A, 5A]
[0]main----6
[0A, 1A, 2A, 3A, 4A, 5A, 6A]
[0]main----7
[0A, 1A, 2A, 3A, 4A, 5A, 6A, 7A]
[0]main----8
[0A, 1A, 2A, 3A, 4A, 5A, 6A, 7A, 8A]
[0]main----9
[0A, 1A, 2A, 3A, 4A, 5A, 6A, 7A, 8A, 9A]
stream
耗时:10188ms
[0A, 1A, 2A, 3A, 4A, 5A, 6A, 7A, 8A, 9A]
  1. m2方法: 使用线程池执行里循环内容
耗时:4ms
list1:null
[1]pool-1-thread-7----6
[1]pool-1-thread-4----3
[1]pool-1-thread-2----1
[1]pool-1-thread-9----8
[1]pool-1-thread-6----5
[1]pool-1-thread-3----2
[1]pool-1-thread-1----0
[1]pool-1-thread-8----7
[1]pool-1-thread-10----9
[1]pool-1-thread-5----4
  1. m3方法:如果不加wait4Done效果个m2一样
[1]pool-1-thread-1----0
[1]pool-1-thread-2----1
[1]pool-1-thread-3----2
[1]pool-1-thread-4----3
[1]pool-1-thread-5----4
[1]pool-1-thread-6----5
[1]pool-1-thread-7----6
[1]pool-1-thread-8----7
[1]pool-1-thread-9----8
[1]pool-1-thread-10----9
耗时:10183ms
list1:[0A, 1A, 2A, 3A, 4A, 5A, 6A, 7A, 8A, 9A]

注意

  1. 使用java stream时,内部不可以访问外部静态变量
  2. 用stream().parallel().forEach(),这个parallel是可以让循环并行的,提高了程序的效率。但是在我使用它往一个list中设置值的时候,发现了问题。由于是多线程异步运行,所以循环可能并不保证全部运行完才进行下一步,所以如果在循环之后对list有其他操作,可能这个list并不完整,这样得到的数据就会有问题。
    所以正确的做法是,如果循环后面没有操作,只是需要在循环体内进行操作的话,用parallel可以提高效率。但是如果循环后面要对循环里面设置的值做操作,就不能使用parallel了。

你可能感兴趣的:(线程池优化for循环)