最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java線程池實現(xiàn)帶返回值的方式方法

 更新時間:2024年09月20日 11:42:12   作者:牛肉胡辣湯  
在Java中,線程池是一種重要的多線程處理方式,可以有效管理和重用線程,提高程序的性能和效率,有時候我們需要在多線程處理中獲取線程的返回值,本文將介紹如何使用線程池實現(xiàn)帶返回值的方式方法,需要的朋友可以參考下

Java線程池帶返回值的方式方法

在Java中,線程池是一種重要的多線程處理方式,可以有效管理和重用線程,提高程序的性能和效率。有時候我們需要在多線程處理中獲取線程的返回值,本文將介紹如何使用線程池實現(xiàn)帶返回值的方式方法。

使用Callable和Future

Java中的Callable接口是一種帶返回值的多線程處理方式,結(jié)合Future接口可以實現(xiàn)獲取線程返回值的功能。下面是一個示例代碼:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadPoolWithReturnValueExample {
    public static void main(String[] args) {
        ExecutorService executor = Executors.newFixedThreadPool(1);
        Callable<Integer> task = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                // 在這里編寫具體的任務邏輯
                return 42; // 返回一個整數(shù)結(jié)果
            }
        };
        Future<Integer> future = executor.submit(task);
        try {
            Integer result = future.get();
            System.out.println("線程返回值為:" + result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        executor.shutdown();
    }
}

在上面的示例中,我們創(chuàng)建了一個Callable匿名類來實現(xiàn)具體的任務邏輯,然后將其提交給線程池進行處理。通過Futureget()方法可以獲取到線程的返回值。

使用CompletionService

除了上面的方法,還可以使用CompletionService來更加靈活地實現(xiàn)帶返回值的線程處理,下面是一個示例代碼:

import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadPoolWithReturnValueExample {
    public static void main(String[] args) throws Exception {
        ExecutorService executor = Executors.newFixedThreadPool(1);
        CompletionService<Integer> completionService = new ExecutorCompletionService<>(executor);
        Callable<Integer> task = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                // 在這里編寫具體的任務邏輯
                return 42; // 返回一個整數(shù)結(jié)果
            }
        };
        completionService.submit(task);
        Future<Integer> future = completionService.take();
        Integer result = future.get();
        System.out.println("線程返回值為:" + result);
        executor.shutdown();
    }
}

在這個示例中,我們使用了CompletionService來管理任務的執(zhí)行和獲取返回值,通過take()方法獲取最先完成的任務結(jié)果。 通過以上方法,我們可以實現(xiàn)在Java中使用線程池帶返回值的方式方法,更好地控制和處理多線程任務,并獲取線程處理的結(jié)果。希望本文對您有所幫助。

會遇到需要處理大量數(shù)據(jù)的情況,使用線程池可以提高數(shù)據(jù)處理的效率。下面是一個示例場景:假設我們有一個包含大量任務的列表,每個任務需要處理一條數(shù)據(jù),并返回處理結(jié)果。我們可以利用線程池來同時處理這些任務,最后獲取結(jié)果并進行統(tǒng)計。

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.*;
public class ThreadPoolBatchDataProcessing {
    public static void main(String[] args) {
        // 模擬生成大量任務數(shù)據(jù)
        List<String> dataList = generateDataList(100);
        // 創(chuàng)建線程池
        ExecutorService executor = Executors.newFixedThreadPool(5);
        // 定義任務列表
        List<Callable<Integer>> tasks = new ArrayList<>();
        for (String data : dataList) {
            tasks.add(() -> {
                // 模擬數(shù)據(jù)處理,這里使用隨機數(shù)表示處理結(jié)果
                Random random = new Random();
                return random.nextInt(100);
            });
        }
        // 批量提交任務
        List<Future<Integer>> futures;
        try {
            futures = executor.invokeAll(tasks);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return;
        }
        int totalResult = 0;
        for (Future<Integer> future : futures) {
            try {
                totalResult += future.get();
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
        System.out.println("所有任務處理完成,結(jié)果總和為:" + totalResult);
        // 關閉線程池
        executor.shutdown();
    }
    // 模擬生成大量數(shù)據(jù)的方法
    private static List<String> generateDataList(int size) {
        List<String> dataList = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            dataList.add("Data-" + i);
        }
        return dataList;
    }
}

在上述示例中,我們模擬了一個需要處理大量數(shù)據(jù)的場景,使用線程池并行處理任務并獲取處理結(jié)果,在最后統(tǒng)計所有任務的處理結(jié)果。這種場景可以幫助提高數(shù)據(jù)處理的效率,特別是對于大規(guī)模數(shù)據(jù)的處理。

線程池是一種管理和復用線程的機制,它可以在程序運行時創(chuàng)建一定數(shù)量的線程,并且在有任務到來時分配線程執(zhí)行任務,執(zhí)行完畢后將線程返回線程池以備重用,從而避免頻繁地創(chuàng)建和銷毀線程,提高了線程的利用率和系統(tǒng)的性能。 下面是線程池的一些重要特點和優(yōu)點:

  1. 重用線程: 線程池會在內(nèi)部維護一定數(shù)量的線程,這些線程可以被重復利用,而不是每次執(zhí)行任務都要創(chuàng)建新線程,減少了線程創(chuàng)建和銷毀的開銷。
  2. 控制最大并發(fā)數(shù): 線程池可以限制可以同時執(zhí)行的線程數(shù)量,可以避免因為線程過多導致系統(tǒng)資源耗盡的問題。
  3. 管理線程: 線程池可以對線程的生命周期進行管理,包括線程的創(chuàng)建、重用、銷毀等操作,讓線程的操作更加可控。
  4. 提高響應速度: 線程池可以讓任務立即執(zhí)行,而不需要等待線程的創(chuàng)建,提高了任務的響應速度。
  5. 降低系統(tǒng)開銷: 使用線程池可以有效控制系統(tǒng)中線程的數(shù)量,避免線程爆炸式增長,從而減少了系統(tǒng)資源的開銷。 常見的線程池類型包括:FixedThreadPool(固定大小線程池)、CachedThreadPool(緩存線程池)、SingleThreadPool(單線程池)和 ScheduledThreadPool(定時任務線程池)等。

拓展:java多線程帶返回值的方式方法

java利用線程池帶有返回值的方式,大體邏輯批量處理大量數(shù)據(jù),啟用線程池,處理完成后將所有的返回內(nèi)容進行組裝拼接

廢話不多說開始看代碼,重點敲黑板:

1.ThreadPoolExecutor 線程池創(chuàng)建

2.CountDownLatch 同步工具類,讓主線程一直等待,直到子線程執(zhí)行完后再執(zhí)行

在這里插入圖片描述

3.listret 用于接收多線程返回值

方式一

使用線程池

// 創(chuàng)建線程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(coresNumber * 2, coresNumber * 2 + 1, 1000, TimeUnit.MINUTES, new LinkedBlockingDeque<>());
         /*創(chuàng)建List用來接收多線程返回的內(nèi)容,泛型里面可以自定義,String或者對象亦或者其他類型*/
        List<Map<String, Object>> listret = new ArrayList<>();
         // 同步工具類,讓主線程一直等待,直到子線程執(zhí)行完后再執(zhí)行
        CountDownLatch downLatch = new CountDownLatch(partition.size());
        // 循環(huán)任務的List
        for (List<String> stringList : partition) {
            // 啟用開啟多個線程
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 開始調(diào)用具體業(yè)務代碼
                        Map<String, Object> mapRet = pmpTargetPriceService.targetPriceThreadTask(stringList, initiateTaskType, userName);
                        listret.add(mapRet);
                    } catch (Exception e) {
                        logger.error("循環(huán)開啟線多線程報錯,調(diào)用下游系統(tǒng)出現(xiàn)錯誤,異常:" + e);
                    } finally {
                        // 業(yè)務邏輯處理完畢,計數(shù)器減一【當前線程處理任務完畢,線程釋放進入線程池,等待處理下一個任務】
                        downLatch.countDown();
                    }
                }
            });
        }
         // 主線程需要等待子任務線程執(zhí)行完,結(jié)果匯總之后,主線程繼續(xù)往下執(zhí)行
        try {
            downLatch.await();
        } catch (Exception e) {
            logger.error("等待超時", e);
            throw new RuntimeException("系統(tǒng)處理超時,請稍后再試");
        }
        // 對返回組裝的list進循環(huán)處理業(yè)務邏輯
        for (Map<String, Object> esbResultPlm1 : listret) {
            // 從Future對象上獲取任務的返回值,并輸出到控制臺
//            Map esbResultPlm1 = (Map) f.get();
            // todo 對我返回的多個map進行拼接
            if (esbResultPlm1.get("status").equals("fail")) {
                failureNum = (int) esbResultPlm1.get("failureNum");
                failureMsg.append(esbResultPlm1.get("msg"));
                map.put("msg", failureMsg.toString());
                failureNumCount += failureNum;

            } else {
                successNum = (int) esbResultPlm1.get("successNum");
                successMsg.append(esbResultPlm1.get("msg"));
                map.put("msg", successMsg.toString());
                successNumCount += successNum;
            }
        }

方法一得到的結(jié)果如下,使用線程池我這里是核數(shù)乘以2是核心線程16,最大17,所以這里最多是16個線程,而且他是無序的隨機分配的

在這里插入圖片描述

在這里插入圖片描述

方式二

重點不用線程池使用@Async注解,但是策略得有所調(diào)整,大體邏輯比如你待處理的數(shù)據(jù)有100條,你可以將這個List按10條為一個新的List,循環(huán)這個集合,在調(diào)用的實際方法上加@Async注解,從而實現(xiàn)多線程加快循環(huán)也是可以的

@Async注意點,加了該注解的方法不能再同一個類,否則無效,其次有可能存在啟動過程@Async UnsatisfiedDependencyException導致 SpringBoot 無法啟動問題解決,我這里是在報錯的類里有注入service或者mapper的注解上加了@Lazy注解就可以

在這里插入圖片描述

        // 將要發(fā)送的集合按10個一組進行重新組裝
        List<List<String>> partition = Lists.partition(list, 10);
         /*創(chuàng)建List用來接收多線程返回的內(nèi)容,泛型里面可以自定義,String或者對象亦或者其他類型*/
        List<Map<String, Object>> listret = new ArrayList<>();
        // 循環(huán)任務的List
        for (List<String> stringList : partition) {
            // 開始調(diào)用具體業(yè)務代碼
            Map<String, Object> mapRet = pmpTargetPriceService.targetPriceThreadTask(stringList, initiateTaskType, userName);
            listret.add(mapRet);
         }
        // 對返回組裝的list進循環(huán)處理業(yè)務邏輯
        for (Map<String, Object> esbResultPlm1 : listret) {
           //對返回的內(nèi)容進行業(yè)務處理
        }
        
// 調(diào)用的方法,返回map
 	@Async
    public Map<String, Object> targetPriceThreadTask(List<String> idList, String initiateTaskType, String userName) throws Exception {
        //具體的邏輯代碼
        Map<String, Object> map = new HashMap();
        return map;
    }

方法二的執(zhí)行結(jié)果,循環(huán)多少次就啟動了多少個子線程,所以這里的想法是先將原生數(shù)組按自定義個進行分配,如有200個任務,分給20個人,每人10個大概就是這樣的思路

在這里插入圖片描述

在這里插入圖片描述

我的完整代碼僅供參考,里面很多類都是我自己業(yè)務用到的,大家可以借鑒

 public Map<String, Object> initiateTargetPriceTask(PmpTargetPriceDTO pmpTargetPriceDTO) throws Exception {
        String userName = SecurityUtils.getUsername();
        Map map = new HashMap();
        List<String> list = Arrays.asList(pmpTargetPriceDTO.getIds());
        // 將要發(fā)送的集合按10個一組進行重新組裝
        List<List<String>> partition = Lists.partition(list, 10);
        // 創(chuàng)建一個線程池
        // 獲取CPU核數(shù)
        int coresNumber = Runtime.getRuntime().availableProcessors();
        System.out.println("獲取CPU核數(shù):" + coresNumber);
        // 創(chuàng)建線程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(coresNumber * 2, coresNumber * 2 + 1, 1000, TimeUnit.MINUTES, new LinkedBlockingDeque<>());
        // 獲取任務發(fā)起類型字段
        String initiateTaskType = pmpTargetPriceDTO.getInitiateTaskType();
        /*創(chuàng)建List用來接收多線程返回的內(nèi)容,泛型里面可以自定義,String或者對象亦或者其他類型*/
        List<Map<String, Object>> listret = new ArrayList<>();
        // 同步工具類,讓主線程一直等待,直到子線程執(zhí)行完后再執(zhí)行
        CountDownLatch downLatch = new CountDownLatch(partition.size());
        // 循環(huán)任務的List
        for (List<String> stringList : partition) {
            // 啟用開啟多個線程
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    try {
                        // 開始調(diào)用具體業(yè)務代碼
                        Map<String, Object> mapRet = pmpTargetPriceService.targetPriceThreadTask(stringList, initiateTaskType, userName);
                        listret.add(mapRet);
                    } catch (Exception e) {
                        logger.error("循環(huán)開啟線多線程報錯,調(diào)用下游系統(tǒng)出現(xiàn)錯誤,異常:" + e);
                    } finally {
                        // 業(yè)務邏輯處理完畢,計數(shù)器減一【當前線程處理任務完畢,線程釋放進入線程池,等待處理下一個任務】
                        downLatch.countDown();
                    }
                }
            });
        }
        // 主線程需要等待子任務線程執(zhí)行完,結(jié)果匯總之后,主線程繼續(xù)往下執(zhí)行
        try {
            downLatch.await();
        } catch (Exception e) {
            logger.error("等待超時", e);
            throw new RuntimeException("系統(tǒng)處理超時,請稍后再試");
        }
        // 關閉線程池
        executor.shutdown();

        // 獲取所有并發(fā)任務的運行結(jié)果
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        int failureNum;
        int successNum;
        int failureNumCount = 0;
        int successNumCount = 0;
        for (Map<String, Object> esbResultPlm1 : listret) {
            // 從Future對象上獲取任務的返回值,并輸出到控制臺
//            Map esbResultPlm1 = (Map) f.get();
            // todo 對我返回的多個map進行拼接
            if (esbResultPlm1.get("status").equals("fail")) {
                failureNum = (int) esbResultPlm1.get("failureNum");
                failureMsg.append(esbResultPlm1.get("msg"));
                map.put("msg", failureMsg.toString());
                failureNumCount += failureNum;

            } else {
                successNum = (int) esbResultPlm1.get("successNum");
                successMsg.append(esbResultPlm1.get("msg"));
                map.put("msg", successMsg.toString());
                successNumCount += successNum;
            }
        }

//        todo 對最終的結(jié)果進行組裝
        if (failureNumCount > 0) {
            failureMsg.insert(0, "很抱歉,發(fā)起任務存在失敗!共發(fā)起 " + list.size() + "條數(shù)據(jù),其中有" + failureNumCount + " 條數(shù)據(jù)格式不正確,錯誤如下:");
            map.put("status", "fail");
            map.put("msg", failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您,數(shù)據(jù)已全部發(fā)起成功!共 " + successNumCount + " 條");
            map.put("status", "success");
            map.put("msg", successMsg.toString());
        }
        return map;
    }
    
    // 調(diào)用的邏輯處理方法
	public Map<String, Object> targetPriceThreadTask(List<String> idList, String initiateTaskType, String userName) throws Exception {
        // 發(fā)起目標價任務
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        StringBuffer NoSubunitmaterialCode = new StringBuffer(); // 子組不存在的物料號合集
        StringBuffer NoSubunit = new StringBuffer(); // 沒有子組的子組號合集
        Map<String, Object> map = new HashMap();
        for (String id : idList) {
            PmpTargetPrice pmpTargetPrice = pmpTargetPriceMapper.selectPmpTargetPriceById(id);
            SysApiRequestLog sysApiRequestLog = new SysApiRequestLog();
            sysApiRequestLog.setRequestMethod("手動發(fā)起目標價任務");
            sysApiRequestLog.setRequestData("物料號:" + pmpTargetPrice.getMaterialCode());
            //查詢是否發(fā)起流程,
            if (pmpTargetPrice.getIsFqlc().equals("1")) {
                failureNum++;
                String msg = "<br/>物料號:" + pmpTargetPrice.getMaterialCode() + "、此物料已經(jīng)發(fā)起過流程,請核實!";
                failureMsg.append(msg);
                continue;
            }
            PmpTargetPriceProcess targetPriceProcess = new PmpTargetPriceProcess();
            //  請求PLM接口
            Map invokeGetPlm = invokeWebService.getInvokeGetPlm(pmpTargetPrice.getMaterialCode());
            targetPriceProcess.setSouce("手動發(fā)起"); // 來源(手動發(fā)起)
            targetPriceProcess.setTaskSponsor(userName);  // 設置發(fā)起人
            targetPriceProcess.setMaterialStatus("0"); // 狀態(tài)
            targetPriceProcess.setInitiateTaskType(initiateTaskType); // 設置手工發(fā)起任務類型
            if (null != invokeGetPlm.get("number").toString()) {
                targetPriceProcess.setMaterialCode(invokeGetPlm.get("number").toString());  // 物料編號
            }
            if (null != invokeGetPlm.get("name").toString()) {
                targetPriceProcess.setMaterialName(invokeGetPlm.get("name").toString());  // 物料名稱
            }
            if (null != invokeGetPlm.get("phase").toString()) {
                targetPriceProcess.setStage(invokeGetPlm.get("phase").toString());//階段
            }
            if (null != invokeGetPlm.get("version").toString()) {
                targetPriceProcess.setVersionNo(invokeGetPlm.get("version").toString()); // 大版本
            }
            if (null != invokeGetPlm.get("state").toString()) {
                targetPriceProcess.setMaterialStatus(invokeGetPlm.get("state").toString()); // 狀態(tài)
            }

            // 請求BOM接口獲取數(shù)據(jù)
            Map materialCode = invokeWebService.getEsbBomMaterialInfo(pmpTargetPrice.getMaterialCode());
            // 截取物料編碼為子組號
            String substring = pmpTargetPriceProcessService.getBlockCode(pmpTargetPrice.getMaterialCode());
            PmpTargetRule targetRule = new PmpTargetRule();
            PmpTargetRule pmpTargetRule;
            String userCode = "";
            // 判斷bom是否有返回,有返回表示有路線,無返回表示無路線
            if (null != materialCode) {
                //根據(jù)物料編號截取的子組取目標規(guī)則表PMP_TARGET_RULE中查
                targetRule.setSonGroup(substring);
                targetRule.setIsRoute("1");
                pmpTargetRule = pmpTargetRuleService.selectPmpTargetRuleBySonGroup(targetRule);

                // 判斷<pmpTargetRule>子組配置是否存在,如根據(jù)子組查詢不存在則設置為特殊子組
                if (!Optional.ofNullable(pmpTargetRule).isPresent()) {
                    targetRule.setSonGroup("特殊件無法獲取");
                    targetRule.setIsRoute("1");
                    pmpTargetRule = pmpTargetRuleService.selectPmpTargetRuleBySonGroup(targetRule);
                }
                /**
                 * 1.一級制造、一級裝配和采購制造均為空時生成任務;
                 * 2.一級制造、一級裝配和采購制造均有值時生成任務;
                 * 3.一級制造、一級裝配有值,采購制造為空時,不生成任務。但要判定一級制造和一級裝配均不含CG時為自制件,
                 * 不生成任務,但返回PLM為S,提示“一級制造和一級裝配均不含CG,為自制件,不生成任務”,
                 * 其他情況返回PLM為E并提示“非自制件,BOM采購制造路線待維護,請稍后發(fā)起定價任務”。
                 */
                String mfmrtg = ""; // 一級制造
                String mfartg = ""; // 一級裝配
                if (StringUtils.isNotBlank(materialCode.get("MFMRTG").toString())
                        && StringUtils.isNotBlank(materialCode.get("MFARTG").toString())
                ) {
                    mfmrtg = materialCode.get("MFMRTG").toString(); // 一級制造
                    mfartg = materialCode.get("MFARTG").toString(); // 一級裝配
                } else {
                    failureNum++;
                    logger.error("物料號:" + pmpTargetPrice.getMaterialCode() + "獲取BOM信息,一級制造或一級裝配為Null,發(fā)起任務失??!");
                    String msg = "<br/>物料號:" + pmpTargetPrice.getMaterialCode() + "、獲取BOM信息,一級制造或一級裝配為Null,發(fā)起任務失??! ";
                    failureMsg.append(msg);
                    sysApiRequestLog.setResponseStatus(EsbResult.RET_STATUS_ERROR);
                    sysApiRequestLog.setErrorLog("手動發(fā)起目標價任務,失敗原因:根據(jù)物料號獲取BOM信息,一級制造或一級裝配為Null,發(fā)起任務失敗");
                    apiRequestLogService.insertSysApiRequestLog(sysApiRequestLog);
                    continue;
                }
//                if (StringUtils.isNotBlank(materialCode.get("MFMRTG").toString())) {
//                    targetPriceProcess.setOneLevelMake(materialCode.get("MFMRTG").toString());  // 一級制造
//                }
//                if (StringUtils.isNotBlank(materialCode.get("MFARTG").toString())) {
//                    targetPriceProcess.setOneLevelAssembling(materialCode.get("MFARTG").toString()); // 一級裝配
//                }
                targetPriceProcess.setOneLevelMake(mfmrtg);  // 一級制造
                targetPriceProcess.setOneLevelAssembling(mfartg); // 一級裝配
                if (StringUtils.isNotBlank(materialCode.get("CFMRTG").toString())) {
                    targetPriceProcess.setPurchaseMake(materialCode.get("CFMRTG").toString());  // 采購制造
                    //根據(jù)BOM接口返回采購制造,如果是PT為研究院,否則為財務部
                    if (targetPriceProcess.getPurchaseMake().equals("PT")) {
                        if (!StringUtils.isEmpty(pmpTargetRule.getYjyDirectorCode())) {
                            targetPriceProcess.setTaskPurchase(pmpTargetRule.getYjyDirectorCode()); // 指定填寫目標價人:研究院
                            // 設置審核人
                            String[] splitYjyCode = pmpTargetRule.getYjyDirectorCode().split("/");
                            userCode = splitYjyCode[0];
                        } else {
                            failureNum++;
                            String msg = "<br/>物料號:" + pmpTargetPrice.getMaterialCode() + "、未獲取到研究院相關人員,請核對! ";
                            failureMsg.append(msg);
                            logger.error("手動發(fā)起目標價任務-物料號-PT-YJY:" + pmpTargetPrice.getMaterialCode() + "設置目標價錄入人時配置有誤,路線為PT,根據(jù)子組查詢但是研究院人員code是未維護發(fā)起任務失??!");
                            sysApiRequestLog.setResponseStatus(EsbResult.RET_STATUS_ERROR);
                            sysApiRequestLog.setErrorLog("手動發(fā)起目標價任務失敗,失敗原因:路線為PT,根據(jù)子組查詢但是研究院人員code是未維護發(fā)起任務失敗");
                            apiRequestLogService.insertSysApiRequestLog(sysApiRequestLog);
                            NoSubunitmaterialCode.append("物料號-PT-YJY:" + pmpTargetPrice.getMaterialCode() + "/");
                            NoSubunit.append("子組號-PT-YJY:" + substring + "/");
                            continue;
                        }
                    } else {
                        if (!StringUtils.isEmpty(pmpTargetRule.getCwDirectorCode())) {
                            targetPriceProcess.setTaskPurchase(pmpTargetRule.getCwDirectorCode()); // 指定填寫目標價人:財務部
                            // 設置審核人
                            String[] splitCwCode = pmpTargetRule.getCwDirectorCode().split("/");
                            userCode = splitCwCode[0];
                        } else {
                            failureNum++;
                            String msg = "<br/>物料號:" + pmpTargetPrice.getMaterialCode() + "、未獲取到財務部相關人員,請核對! ";
                            failureMsg.append(msg);
                            logger.error("手動發(fā)起目標價任務-物料號-非PT-CW:" + pmpTargetPrice.getMaterialCode() + "設置目標價錄入人時配置有誤,路線非PT,根據(jù)子組查詢財務人員code是Null發(fā)起任務失??!");
                            sysApiRequestLog.setResponseStatus(EsbResult.RET_STATUS_ERROR);
                            sysApiRequestLog.setErrorLog("手動發(fā)起目標價任務,失敗原因:根據(jù)子組查詢財務人員code是Null發(fā)起任務失敗");
                            apiRequestLogService.insertSysApiRequestLog(sysApiRequestLog);
                            NoSubunitmaterialCode.append("物料號-非PT-CW:" + pmpTargetPrice.getMaterialCode() + "/");
                            NoSubunit.append("子組號-非PT-CW:" + substring + "/");
                            continue;
                        }
                    }
                } else {
                    if (!mfmrtg.equals("CG") || !mfartg.equals("CG")) {
                        logger.error("物料號:" + pmpTargetPrice.getMaterialCode() + "一級制造和一級裝配均不含CG,為自制件,不生成任務!");
                        failureNum++;
                        String msg = "<br/>物料號:" + pmpTargetPrice.getMaterialCode() + "、一級制造和一級裝配均不含CG,為自制件,不生成任務! ";
                        failureMsg.append(msg);
                        sysApiRequestLog.setResponseStatus(EsbResult.RET_STATUS_ERROR);
                        sysApiRequestLog.setErrorLog("手動發(fā)起目標價任務,失敗原因:一級制造和一級裝配均不含CG,為自制件,不生成任務!");
                        continue;
                    } else {
                        failureNum++;
                        String msg = "<br/>物料號:" + pmpTargetPrice.getMaterialCode() + "、BOM采購制造路線待維護,請稍后發(fā)起定價任務!";
                        failureMsg.append(msg);
                        sysApiRequestLog.setResponseStatus(EsbResult.RET_STATUS_ERROR);
                        sysApiRequestLog.setErrorLog("手動發(fā)起目標價任務,失敗原因:BOM采購制造路線待維護,請稍后發(fā)起定價任務!");
                        continue;
                    }
                }
            } else {
                // 無路線
                targetRule.setSonGroup(substring);
                targetRule.setIsRoute("0");
                pmpTargetRule = pmpTargetRuleService.selectPmpTargetRuleBySonGroup(targetRule);
                /**
                 * 其他特殊件,無法獲取子組,
                 * PT或無路線由研究院鄭宇處理,
                 * 非PT的由財務部蘇戰(zhàn)波和趙偉處理
                 */
                if (!Optional.ofNullable(pmpTargetRule).isPresent()) {
                    targetRule.setSonGroup("特殊件無法獲取");
                    targetRule.setIsRoute("1");
                    pmpTargetRule = pmpTargetRuleService.selectPmpTargetRuleBySonGroup(targetRule);
                }
                if (null != pmpTargetRule && StringUtils.isNotBlank(pmpTargetRule.getYjyDirectorCode())) {
                    targetPriceProcess.setTaskPurchase(pmpTargetRule.getYjyDirectorCode()); // 指定填寫目標價人:研究院
                    String[] splitYjyCode = pmpTargetRule.getYjyDirectorCode().split("/");
                    userCode = splitYjyCode[0];
                } else {
                    failureNum++;
                    String msg = "<br/>物料號:" + pmpTargetPrice.getMaterialCode() + "、未獲取到研究院相關人員(無路線),請核對! ";
                    failureMsg.append(msg);
                    continue;
                }
            }

            // todo 判斷任務是研究院或者財務,設置審核人
            // 查詢研究院,財務或者無路線任務辦理人,并獲取他們的部門編碼,向上尋找審核人
            if (!userCode.equals("")) {
                SysUser sysUser = userService.selectUserByUserName(userCode);
                if (StringUtils.isNotNull(sysUser)) {
                    // 截取部門code
                    String deptCode = "";
                    if (sysUser.getDeptId().length() > 9) {
                        deptCode = sysUser.getDeptId().substring(0, 9);
                    } else {
                        deptCode = sysUser.getDeptId();
                    }
                    //查詢審核配置表,查到審核人,插入目標價
                    PmpTargetAuditConfig pmpTargetAuditConfig = pmpTargetAuditConfigService.selectPmpTargetAuditConfigByDeptCode(deptCode);
                    targetPriceProcess.setCheckName(pmpTargetAuditConfig.getAuditor());
                }
            }
            //已發(fā)起流程
            pmpTargetPrice.setIsFqlc("1");
            targetPriceProcess.setStatus("0"); // 任務狀態(tài) 0待定級發(fā)起
            targetPriceProcess.setQuejiaType("目標價"); // 缺價類型默認目標價
            //添加任務發(fā)起人
            targetPriceProcess.setTaskSponsor(userName);
            targetPriceProcess.setCreateBy(userName);
            pmpTargetPriceMapper.updatePmpTargetPrice(pmpTargetPrice);
            if (StringUtils.isEmpty(targetPriceProcess.getMaterialName())) {
                targetPriceProcess.setMaterialName(pmpTargetPrice.getMaterialName());
            }
            /**
             * 查看當前物料號在目標價任務表中是否存在,最后的檢查
             */
            PmpTargetPriceProcess priceProcess = new PmpTargetPriceProcess();
            priceProcess.setMaterialCode(targetPriceProcess.getMaterialCode());
            priceProcess.setStatus("0,1,2,4");
            PmpTargetPriceProcess pmpTargetPriceProcess = targetPriceProcessService.selectPmpTargetPriceProcessByEntity(priceProcess);
            if (null != pmpTargetPriceProcess) {
                continue;
            }
            // 設置任務號
            String newsNo = DateUtils.parseDateToStr("yyyyMMdd", new Date());
            int count = targetPriceProcessService.getFindTaskCount();
            String format = String.format("%05d", count);
            //  任務編號 MBJRW+年月日+流水號
            targetPriceProcess.setTaskNumber("MBJRW" + newsNo + format);
            targetPriceProcessService.insertPmpTargetPriceProcess(targetPriceProcess);
            successNum++;
        }
        if (failureNum > 0) {
//            failureMsg.insert(0, "很抱歉,發(fā)起任務存在失?。」?" + failureNum + " 條數(shù)據(jù)格式不正確,錯誤如下:");
            map.put("status", "fail");
            map.put("msg", failureMsg.toString());
            map.put("failureNum", failureNum);
        } else {
//            successMsg.insert(0, "恭喜您,數(shù)據(jù)已全部發(fā)起成功!共 " + successNum + " 條");
            map.put("status", "success");
            map.put("msg", successMsg.toString());
            map.put("successNum", successNum);
        }
        logger.info("手動發(fā)起目標價任務結(jié)束!");
        logger.info("手動發(fā)起目標價-物料號查找子組有誤的物料統(tǒng)計:" + NoSubunitmaterialCode.toString());
        logger.info("手動發(fā)起目標價-物料號查找子組有誤的子組號統(tǒng)計:" + NoSubunit.toString());
        return map;
    }
    

總結(jié)方式一和方式二都能解決加快任務處理,處理時間都差不讀多,大家可以挑選自己適合的方式,如有更好的方式或不對的點請指正,歡迎大家溝通交流,共同成長進步

到此這篇關于Java線程池實現(xiàn)帶返回值的方式方法的文章就介紹到這了,更多相關Java線程池帶返回值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 教你怎么解決IDEA中“\t“空格顯示不正確的問題

    教你怎么解決IDEA中“\t“空格顯示不正確的問題

    在之前進行先來先服務(FCFS)調(diào)度算法的模擬過程中,使用IDEA進行開發(fā)時遇到了"\t"無法補全當前字符串長度到8的整數(shù)倍的問題.百度一圈發(fā)現(xiàn)也有很多程序員遇到了這樣的問題,但是沒有解決方法,于是有了這篇文章,需要的朋友可以參考下
    2021-05-05
  • springboot集成shiro自定義登陸過濾器方法

    springboot集成shiro自定義登陸過濾器方法

    這篇文章主要介紹了springboot集成shiro自定義登陸過濾器方法,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • 項目連接nacos配置中心報錯:Client not connected, current status:STARTING的解決方案

    項目連接nacos配置中心報錯:Client not connected, current

    這篇文章主要介紹了項目連接nacos配置中心報錯:Client not connected, current status:STARTING的解決方案,采用了mysql作為持久化的數(shù)據(jù)庫,docker作為運行的環(huán)境,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • java判斷某個點是否在所畫多邊形/圓形內(nèi)

    java判斷某個點是否在所畫多邊形/圓形內(nèi)

    這篇文章主要為大家詳細介紹了java判斷某個點是否在所畫多邊形或圓形內(nèi)的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • Java大批量導出Excel數(shù)據(jù)的優(yōu)化過程

    Java大批量導出Excel數(shù)據(jù)的優(yōu)化過程

    幾十萬上百萬行的數(shù)據(jù)是很常見的。本文主要介紹了Java大批量導出Excel數(shù)據(jù)的優(yōu)化過程,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • SpringBoot集成ShardingSphere-JDBC實現(xiàn)分庫分表

    SpringBoot集成ShardingSphere-JDBC實現(xiàn)分庫分表

    本文主要介紹了SpringBoot集成ShardingSphere-JDBC實現(xiàn)分庫分表,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2025-07-07
  • JAVA實現(xiàn)線程的三種方法

    JAVA實現(xiàn)線程的三種方法

    這篇文章介紹了JAVA實現(xiàn)線程的三種方法,有需要的朋友可以參考一下
    2013-09-09
  • Java中的定時任務調(diào)度Quartz舉例詳解

    Java中的定時任務調(diào)度Quartz舉例詳解

    這篇文章主要介紹了Java中的定時任務調(diào)度Quartz的相關資料,Quartz是Java平臺上的一個強大且靈活的任務調(diào)度庫,廣泛應用于企業(yè)級應用中,本文介紹了Quartz的基本概念、核心組件、使用步驟和示例,幫助你更好地利用Quartz進行定時任務調(diào)度,需要的朋友可以參考下
    2024-12-12
  • Java經(jīng)典面試題匯總:網(wǎng)絡編程

    Java經(jīng)典面試題匯總:網(wǎng)絡編程

    本篇總結(jié)的是Java 網(wǎng)絡編程相關的面試題,后續(xù)會持續(xù)更新,希望我的分享可以幫助到正在備戰(zhàn)面試的實習生或者已經(jīng)工作的同行,如果發(fā)現(xiàn)錯誤還望大家多多包涵,不吝賜教,謝謝
    2021-07-07
  • springmvc實現(xiàn)自定義類型轉(zhuǎn)換器示例

    springmvc實現(xiàn)自定義類型轉(zhuǎn)換器示例

    本篇文章主要介紹了springmvc實現(xiàn)自定義類型轉(zhuǎn)換器示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02

最新評論

莱芜市| 偏关县| 宁强县| 古丈县| 靖安县| 清徐县| 平泉县| 安新县| 云龙县| 邵阳县| 兰坪| 沙洋县| 东乡族自治县| 阿尔山市| 理塘县| 永嘉县| 砚山县| 容城县| 抚顺县| 招远市| 托克逊县| 东平县| 夏邑县| 夹江县| 巴南区| 扎囊县| 邯郸市| 永寿县| 和平县| 毕节市| 辉县市| 吉水县| 玉龙| 安多县| 建始县| 古田县| 海晏县| 读书| 马关县| 西昌市| 丹寨县|