使用countdownlatch和线程池fixedThreadPool实现任务的分发执行

业务逻辑要求:每次调用多个任务,将任务分发给多个子线程,实现并行执行。本代码使用缓存线程池cacheThreadPool初始化多个线程,使用countdownlatch做子线程的计数控制,当子线程执行完,释放执行权,交给主线程,开始下一轮的执行。

话不多说:上代码

package com.test.thread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by liujianfu on 2018/11/17.
 */
public class BatchTest {

    private static int count=0;
    //线程数
    /**
     * @param args
     */

    public static void main(String[] args) {
        while (true) {
            if (count == 1) {
                System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "执行结束");
                break;
            }
            //1.获取任务,设定10任务,待线程分配处理
            final List<Integer> taskList = new ArrayList<Integer>();
            for (int k = 0; k < 10; k++) {
                System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "查询集合");
                taskList.add(k);
            }
            //线程数
            int num = 5;
            //CountDownLatch是一个同步辅助类也可以使用AtomicInteger替代
            final CountDownLatch doneSignal = new CountDownLatch(num);
            ExecutorService pool = Executors.newFixedThreadPool(num);
            final BatchTest t =new BatchTest();
            for (int k = 0; k < num; k++) {
                //在未来某个时间执行给定的命令
                System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "开始执行");
                final List<Integer> list = doWork(k, taskList);
                System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "获得任务集合");
                pool.execute(new Runnable() {

                    public void run() {
                        //子线程的任务
                        try {
                            //  System.out.println("线程:"+i+"休眠。。。。。");
                            System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "休眠:");
                            Thread.sleep(1000);
                            t.consumer(list);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        //任务执行完毕递减锁存器的计数
                        System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "count前");
                        doneSignal.countDown();
                        System.out.println("线程名字:" + Thread.currentThread().getName() + " 线程id:" + Thread.currentThread().getId() + "count后");

                    }
                });
            }
                try {
                    System.out.println("await前");
                    doneSignal.await();
                    System.out.println("await后");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //子线程执行完毕,可以开始后续任务处理了
                System.out.println("所有任务执行完毕");
                count++;
                System.out.println("========");

        }
    }

    public  static  List<Integer> doWork(int i,List<Integer> taskList) {
        int totalSize = taskList.size();
        int ts = 5;
        if (ts > totalSize) {
            ts = totalSize;
        }
        int m = totalSize / ts;

        int startIndex = i * m;
        int endIndex = (i + 1) * m;
        if (i == ts - 1) {
            endIndex = totalSize;
        }
        List<Integer> tempIds = taskList.subList(startIndex, endIndex);
        return tempIds;
    }
    public void consumer(List<Integer> tempIds){
        for(int k=0;k<tempIds.size();k++){
            System.out.println("线程名字:"+Thread.currentThread().getName()+" 线程id:"+Thread.currentThread().getId()+"消费任务:"+tempIds.get(k));
        }
        System.out.println("线程名字:"+Thread.currentThread().getName()+" 线程id:"+Thread.currentThread().getId()+"本线程消费结束");
    }
}

执行结果:

线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1查询集合
线程名字:main 线程id:1开始执行
线程名字:main 线程id:1获得任务集合
线程名字:main 线程id:1开始执行
线程名字:main 线程id:1获得任务集合
线程名字:main 线程id:1开始执行
线程名字:main 线程id:1获得任务集合
线程名字:pool-1-thread-1 线程id:11休眠:
线程名字:main 线程id:1开始执行
线程名字:main 线程id:1获得任务集合
线程名字:pool-1-thread-3 线程id:13休眠:
线程名字:main 线程id:1开始执行
线程名字:main 线程id:1获得任务集合
await前
线程名字:pool-1-thread-5 线程id:15休眠:
线程名字:pool-1-thread-2 线程id:12休眠:
线程名字:pool-1-thread-4 线程id:14休眠:
线程名字:pool-1-thread-1 线程id:11消费任务:0
线程名字:pool-1-thread-1 线程id:11消费任务:1
线程名字:pool-1-thread-1 线程id:11本线程消费结束
线程名字:pool-1-thread-1 线程id:11count前
线程名字:pool-1-thread-1 线程id:11count后
线程名字:pool-1-thread-3 线程id:13消费任务:4
线程名字:pool-1-thread-3 线程id:13消费任务:5
线程名字:pool-1-thread-3 线程id:13本线程消费结束
线程名字:pool-1-thread-3 线程id:13count前
线程名字:pool-1-thread-3 线程id:13count后
线程名字:pool-1-thread-2 线程id:12消费任务:2
线程名字:pool-1-thread-2 线程id:12消费任务:3
线程名字:pool-1-thread-2 线程id:12本线程消费结束
线程名字:pool-1-thread-2 线程id:12count前
线程名字:pool-1-thread-2 线程id:12count后
线程名字:pool-1-thread-5 线程id:15消费任务:8
线程名字:pool-1-thread-5 线程id:15消费任务:9
线程名字:pool-1-thread-5 线程id:15本线程消费结束
线程名字:pool-1-thread-5 线程id:15count前
线程名字:pool-1-thread-5 线程id:15count后
线程名字:pool-1-thread-4 线程id:14消费任务:6
线程名字:pool-1-thread-4 线程id:14消费任务:7
线程名字:pool-1-thread-4 线程id:14本线程消费结束
线程名字:pool-1-thread-4 线程id:14count前
线程名字:pool-1-thread-4 线程id:14count后
await后
所有任务执行完毕

========
线程名字:main 线程id:1执行结束

可以看到:10个任务,分配给5个线程,每个线程分别获取2个线程,获取的线程彼此不相交。

都看到这里了,就顺手点击左上角的【关注】按钮,点击右上角的小手,给个评论,关注一下,再走呗!☺

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值