线程池实现多线程的并行执行和串行执行

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.rules.Stopwatch;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.StopWatch;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 *  
 */
@Slf4j
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = ExecutorTest.class)
public class ExecutorTest {
    private Runnable mActive;
    private ArrayDeque<Runnable> mArrayDeque = new ArrayDeque<>();
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    private static final int KEEP_ALIVE = 1;
    private static final BlockingQueue sPoolWorkQueue = new LinkedBlockingDeque<>(128);
    private static final ThreadFactory sThreadFactory = new ThreadFactory() {
        private final AtomicInteger mCount = new AtomicInteger(1);
        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "Serial thread #" + mCount.getAndIncrement());
        }
    };
    private static final ThreadPoolExecutor THREAD_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE,
    MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

    /**
     * 测试并行线程处理后再合并结果到主线程
     * @throws InterruptedException
     */
    @Test
    public void Parallel() throws InterruptedException {
        StopWatch sw = new StopWatch();
        sw.start();
        System.out.println("开始执行并行多线程任务... ...");
        List<String> list = new ArrayList<String>();//任务返回结果
        CountDownLatch countDownLatch = new CountDownLatch(10);//CountDownLatch是一个同步工具类,它通过一个计数器来实现的,初始值为线程的数量。每当一个线程完成了自己的任务,计数器的值就相应得减1。当计数器到达0时,表示所有的线程都已执行完毕,然后在等待的线程就可以恢复执行任务n
        /**
         * int corePoolSize 核心线程大小
         * int maximumPoolSize  线程池最大容量大小
         * long keepAliveTime 线程空闲时间,线程存活时间
         * TimeUnit unit 时间单位
         * BlockingQueue<Runnable> workQueue 任务队列 一个阻塞队列
         */
        ExecutorService executorService = new ThreadPoolExecutor(10,10,0l, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());//创建线程池
        for(int i=0;i<10;i++){
            System.out.println("线程准备中... ...");
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(3000);
                        list.add(UUID.randomUUID().toString());
                        System.out.println("当前线程name:"+Thread.currentThread().getName());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally{
                        countDownLatch.countDown();
                    }

                }
            };
            executorService.execute(runnable);
        }
        System.out.println("countDownLatch.getCount():"+countDownLatch.getCount());
        countDownLatch.await();//主线程阻塞
        System.out.println("下一步:countDownLatch.getCount():"+countDownLatch.getCount());
        sw.stop();
        System.out.println("submit总共cost时间:"+sw.getTotalTimeMillis());
        executorService.shutdown();//等待线程执行完成,停止线程
        System.out.println(list);//打印线程执行结果
    }


    /**
     * 测试串行线程一个个的执行线程,执行结束后再执行主线程任务
     */
    @Test
    public void Serial() throws InterruptedException, ExecutionException {
        StopWatch sw = new StopWatch();
        sw.start();
        System.out.println("开始执行串行多线程任务... ...");
        List<String> list = new ArrayList<String>();//任务的返回结果
        CountDownLatch countDownLatch = new CountDownLatch(10);
        LinkedBlockingQueue<Runnable> tasks = new LinkedBlockingQueue<>();
        //创建一个线程池
        /**
         * int corePoolSize 核心线程大小
         * int maximumPoolSize  线程池最大容量大小
         * long keepAliveTime 线程空闲时间,线程存活时间
         * TimeUnit unit 时间单位
         * BlockingQueue<Runnable> workQueue 任务队列 一个阻塞队列
         */
        //方式二 先创建一个线程池 使用callable的阻塞方式实现多线程的串行执行
        ExecutorService executorService = new ThreadPoolExecutor(10,10,0l,TimeUnit.MILLISECONDS,tasks);

//       ExecutorService executorService = Executors.newSingleThreadExecutor();//方式一使用单线程方式实现线程串行执行
        List<Callable<Integer>> lr = new ArrayList<Callable<Integer>>();
        for(int i=0;i<10;i++){
            System.out.println("线程准备中... ...");
            int finalI = i;
            Callable callable = new Callable<Integer>() {
                public Integer call() throws Exception {

                    list.add(UUID.randomUUID().toString());
                    System.out.println(finalI+"当前线程name:"+Thread.currentThread().getName());
                    countDownLatch.countDown();
                    return finalI;
                }
            };
            Future submit = executorService.submit(callable);
            Object o = submit.get();
            lr.add(callable);
        }

//        List<Future<Integer>> futures = executorService.invokeAll(lr);
//
//        for(Future<Integer> f:futures){
//            try {
//                System.out.println(f.get());
//            } catch (ExecutionException e) {
//            e.printStackTrace();
//            }
//        }


//        try {
//            Thread.sleep(1500);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        System.out.println("countDownLatch.getCount():"+countDownLatch.getCount());
        countDownLatch.await();//主线程阻塞
        System.out.println("下一步:countDownLatch.getCount():"+countDownLatch.getCount());
        sw.stop();
        System.out.println("submit总共cost时间:"+sw.getTotalTimeMillis());
        executorService.shutdown();//等待线程执行完成,停止线程
        System.out.println(list);//打印线程执行结果
    }
    /**
     * 测试串行线程一个个的执行线程,执行结束后再执行主线程任务
     */
    @Test
    public void Serial2() throws InterruptedException, ExecutionException {
        StopWatch sw = new StopWatch();
        sw.start();
        System.out.println("开始执行串行多线程任务... ...");
        List<String> list = new ArrayList<String>();//任务的返回结果
        CountDownLatch countDownLatch = new CountDownLatch(10);
        LinkedBlockingQueue<Runnable> tasks = new LinkedBlockingQueue<>();
        //创建一个线程池
       ExecutorService executorService = Executors.newSingleThreadExecutor();//方式一使用单线程方式实现线程串行执行
        List<Callable<Integer>> lr = new ArrayList<Callable<Integer>>();
        for(int i=0;i<10;i++){
            System.out.println("线程准备中... ...");
            int finalI = i;
            Callable callable = new Callable<Integer>() {
                public Integer call() throws Exception {

                    list.add(UUID.randomUUID().toString());
                    System.out.println(finalI+"当前线程name:"+Thread.currentThread().getName());
                    countDownLatch.countDown();
                    return finalI;
                }
            };
            lr.add(callable);
        }

        List<Future<Integer>> futures = executorService.invokeAll(lr);
//
        for(Future<Integer> f:futures){
            try {
                System.out.println(f.get());
            } catch (ExecutionException e) {
            e.printStackTrace();
            }
        }


//        try {
//            Thread.sleep(1500);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        System.out.println("countDownLatch.getCount():"+countDownLatch.getCount());
        countDownLatch.await();//主线程阻塞
        System.out.println("下一步:countDownLatch.getCount():"+countDownLatch.getCount());
        sw.stop();
        System.out.println("submit总共cost时间:"+sw.getTotalTimeMillis());
        executorService.shutdown();//等待线程执行完成,停止线程
        System.out.println(list);//打印线程执行结果
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值