JUC中CountDownLatch和Semaphore的应用

1 基本使用

 要求
 1 大量线程希望分批次执行,批次间同步,批次可以异步执行
 2 系统有最大线程数限制,不可以同时创建大量线程
    public static void main(String[] args) throws InterruptedException {
        //任务数量      最大线程数               每一批任务数量
        int jobs = 11, MAX_THREAD_NUMBER = 3, BATCH_NUMBER = 5;
        Semaphore semaphore = new Semaphore(MAX_THREAD_NUMBER);
        //循环几批
        int loops = jobs / BATCH_NUMBER + jobs % BATCH_NUMBER;

        for (int i = 0; i < loops; i++) {
            //本批次剩余任务数
            int left_job = Math.min(BATCH_NUMBER, jobs - i * BATCH_NUMBER);
            CountDownLatch countDownLatch = new CountDownLatch(left_job);
            System.err.printf("第 %d 批数据开始执行,总共 %d 个数据\n", i + 1, left_job);
            for (int j = 0; j < left_job; j++) {
                int finalI = i, finalJ = j;
                new Thread(() -> {
                    try {
                        semaphore.acquire();
                        Thread.sleep(new Random().nextInt(200));
                        System.err.printf("第 %d 批第 %d 个数据执行完毕\n", finalI + 1, finalJ + 1);
                        semaphore.release();
                        countDownLatch.countDown();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }).start();
            }
            countDownLatch.await();
            System.err.printf("第 %d 批数据执行完毕,这里统一处理这批数据...\n", i + 1);
            Thread.sleep(new Random().nextInt(1000));
        }
    }

执行结果

1 批数据开始执行,总共 5 个数据
第 1 批第 1 个数据执行完毕
第 1 批第 4 个数据执行完毕
第 1 批第 2 个数据执行完毕
第 1 批第 3 个数据执行完毕
第 1 批第 5 个数据执行完毕
第 1 批数据执行完毕,这里统一处理这批数据...2 批数据开始执行,总共 5 个数据
第 2 批第 1 个数据执行完毕
第 2 批第 2 个数据执行完毕
第 2 批第 5 个数据执行完毕
第 2 批第 3 个数据执行完毕
第 2 批第 4 个数据执行完毕
第 2 批数据执行完毕,这里统一处理这批数据...3 批数据开始执行,总共 1 个数据
第 3 批第 1 个数据执行完毕
第 3 批数据执行完毕,这里统一处理这批数据...

2 优化写excel

public class ExcelUtils {
		//每个sheet最大行数,超过则创建新sheet
    public static final int SHEET_MAX_ROWS = 20_0000;

    public static <T> Workbook write(List<T> list, String[] header) throws InterruptedException {
        Workbook workbook = new XSSFWorkbook();
        int sheets = (int) Math.ceil(list.size() / (SHEET_MAX_ROWS + 0.0));

        Semaphore semaphore = new Semaphore(5);
        CountDownLatch countDownLatch = new CountDownLatch(sheets);
        for (int i = 0; i < sheets; i++) {
            Sheet sheet = workbook.createSheet();

            int finalI = i;
            new Thread(() -> {
                try {
                    semaphore.acquire();
                    doWrite(list, finalI, sheet, header);
                } catch (IllegalAccessException | InterruptedException e) {
                    throw new RuntimeException(e);
                } finally {
                    semaphore.release();
                    countDownLatch.countDown();
                }
            }).start();
        }
        countDownLatch.await();
        return workbook;
    }

    private static <T> void doWrite(List<T> list, int from, Sheet sheet, String[] header) throws IllegalAccessException {
        int start = from * SHEET_MAX_ROWS;
        int end = Math.min(SHEET_MAX_ROWS, list.size() - start);

        doWriteHeader(sheet.createRow(0), header);
        for (int i = start; i < start + end; i++) {
            Row row = sheet.createRow(i + 1 - start);
            T t = list.get(i);
            doWriteValue(t, row);
        }
    }

    private static void doWriteHeader(Row row, String[] header) {
        for (int i = 0; i < header.length; i++) {
            row.createCell(i, CellType.STRING).setCellValue(header[i]);
        }
    }

    private static <T> void doWriteValue(T t, Row row) throws IllegalAccessException {
        Field[] fields = t.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            Field field = fields[i];
            if (field.getName().equals("HEADER")) continue;
            field.setAccessible(true);
            Object o = field.get(t);
            if (o instanceof String) {
                row.createCell(i, CellType.STRING).setCellValue((String) o);
            } else if (o instanceof Integer) {
                row.createCell(i, CellType.NUMERIC).setCellValue((int) o);
            } else if (o instanceof Boolean) {
                row.createCell(i, CellType.BOOLEAN).setCellValue((Boolean) o);
            } else {
                row.createCell(i, CellType.BLANK).setCellValue(String.valueOf(o));
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值