多線程執(zhí)行門店選品任務

1.背景

連鎖零售公司旗下有1000家門店,每個門店的選品過程都是獨立的,每個門店選品執(zhí)行的時間平均為30秒,單線程串行執(zhí)行所有門店選品需要500分鐘,因為業(yè)務上下游給的時間有限,需要減少整體的執(zhí)行時間,執(zhí)行時間控制在100分鐘內。

2.思路

并行執(zhí)行,500/100=5,同時有五家門店在選品,單臺機器并發(fā)執(zhí)行的能力是有限,若超過單臺機器的并發(fā)能力可以用定時任務分片的方式來擴展并發(fā)能力。

3.模擬代碼

3.1.門店選品

/**
 * 門店選品
 *
public class StoreSelection {

    /**
     * 門店編碼
     */
    private String storeCode;

    private final static String TXT = "門店選品開始門店選品開始門店選品開始門店選品開始門店選品開始門店選品開始門店選品開始門店選品開始門店選品開始";

    public StoreSelection(String storeCode) {
        this.storeCode = storeCode;
    }

    public String select(){
        System.out.println(String.format("%s門店編碼=%s的門店選品開始",  LocalDateTime.now(), storeCode));
        Base64.Encoder encoder = Base64.getEncoder();
        LocalDateTime start = LocalDateTime.now();
        LocalDateTime end = start.plusSeconds(30);
        //模擬選品過程中有異常
        if ("A10".equals(storeCode)) {
            throw new RuntimeException(storeCode + "門店選品異常請?zhí)幚?);
        }
        while (LocalDateTime.now().isBefore(end)) {
            //加重CPU負載
            encoder.encode(TXT.getBytes());
            //System.out.println(String.format("%s門店編碼=%s的門店選品執(zhí)行中", LocalDateTime.now(), storeCode));
        }
        System.out.println(String.format("%s門店編碼=%s的門店選品完成", LocalDateTime.now(), storeCode));
        return  storeCode + "門店選品完成";
    }

    public static void main( String[] args ) {
        new StoreSelection("A1").select();
    }
}

3.2.連鎖零售公司旗下所有門店選品

public class GroupSelection{

    public static void main( String[] args ) {
        List<String> storeCodeList = new LinkedList<>();
        for (int i = 0; i < 1000; i++) {
            storeCodeList.add("A"+i);
        }
        System.out.println("門店組選品開始");
        ExecutorService executor = Executors.newFixedThreadPool(5);
        List<Future<String>> futureList = storeCodeList.stream()
                .map(storeCode -> executor.submit(() -> new StoreSelection(storeCode).select()))
                .collect(Collectors.toList());
        while(!futureList.stream().allMatch(Future::isDone)){
            System.out.println("等待所有門店選品執(zhí)行結束");
        }
        String re  = futureList.stream().map(future -> {
            try {
                return future.get();
            } catch (ExecutionException | InterruptedException e) {
                e.printStackTrace();
                return e.getMessage();
            }
        }).collect(Collectors.joining(","));
        System.out.println(re);
        System.out.println("門店組選品完成");
        executor.shutdown();
    }

}

4.隱患

4.1.隨著公司的擴張門店數(shù),線程池里的隊列膨脹,可能導致OOM

5.可改進

5.1 使用CompletableFuture

5.2 日志改用slf4j

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容