實現多線程Callable接口


Callable接口,實現多線程

 1.實現 Callable接口,相較於實現 Runnable 接口的方式,優點是:方法可以有返回值,並且可以拋出異常

 2.需要 FutureTask實現類的支持,用於接收運算結果

 3.result.get(),接收返回的計算結果,在所有的線程沒有執行完成之后這里是不會執行的

實現Callable接口

public class RealTimeRiskCallable implements Callable<RealTimeRisk> {
    
    private Logger logger =LoggerFactory.getLogger(RealTimeRiskThread.class);
    private String path;//文件路徑
    private Integer count;//計算文件名稱加的區別
    private List<String> deviceName;//設備名稱
    private RealTimeRisk realTimeRisk=new RealTimeRisk();//接收風險計算的結果
    
    public RealTimeRiskCallable(String path, Integer count,List<String> deviceName) {
        this.path = path;
        this.count = count;
        this.deviceName = deviceName;
    }
    
    @Override
    public RealTimeRisk call() throws Exception {
        try {
            String path=this.path;//到時候讀取配置文件進行配置
            String bpaPath="BPA_EXE_PATH"+this.count;
            String realFilePath=path.substring(0,path.lastIndexOf("/"))+File.separator+"copyZh"+this.count+".dat";
            FileUtil.copyFile(path, realFilePath);//復制一個copyZh.dat文件,真正用這個
            path=realFilePath;
            new HealingDat().healing(path,bpaPath);
            ExecuteBPA bpa=ExecuteBPA.getANewInstance();
            Integer code = bpa.execute(path,bpaPath);
            if(code != 5) {
                System.err.println("dat文件計算出錯!");
            }else{
                double lostdata=ElectricityUtil.getLoadData(bpa);//沒有操作之前的負荷數據(損失負荷=操作之前的負荷數據-操作過后的負荷數據)
                ElectricityUtil.setNormalData(lostdata);//存放沒有操作之前的負荷值
                ReadAndWriteDAT readAndWriteDAT =ReadAndWriteDAT.getANewInstance(path);
                EquipmentVo.setAutoStopBusCard(readAndWriteDAT.getAllNoteBCard());// 文件操作前注釋的b卡(之后-之前=失壓的母線)
                List<String> list2 =ElectricityUtil.countStation(bpa.readDatFile());
                EquipmentVo.setThridStationNames(list2);//這里借用了setThridStationNames這個存放值
                System.out.println(lostdata);
            }
            logger.info("開始讀取dat文件...");
            long start =System.currentTimeMillis();
            DataSourceUtil.replaceFileStr(path, this.deviceName);//進行dat對應操作
            long end =System.currentTimeMillis();
            logger.info("重新寫入dat文件成功!耗時:"+(end-start)/1000+"S");
            realTimeRisk=new RealTimeRiskManagerImpl().nowRisk(path,bpaPath);//實時風險計算
            logger.info("實時風險計算成功!");
        } catch (Exception e) {
            logger.info("實時風險計算失敗!");
            e.printStackTrace();
        }
        return realTimeRisk;
    }
    public void setCount(Integer count) {
        this.count = count;
    }
    public void setDeviceName(List<String> deviceName) {
        this.deviceName = deviceName;
    }
}

調用:

                    /**
                     * 多線程進行計算
                     */
                    List<RealTimeRisk> allResult =new ArrayList<RealTimeRisk>();
                    /*//測試數據
                    list.clear();
                    list.add("<name=南連乙線#type=線路>");
                    list.add("<name=廣生站#1主變#type=主變><name=廣生站#2主變#type=主變>"); 
                    list.add("<name=廣生站#2主變#type=主變>");*/ 
                    ExecutorService executorService = Executors.newCachedThreadPool();
                    RealTimeRiskCallable realTimeRiskCallable1= null;
                    RealTimeRiskCallable realTimeRiskCallable2= null;
                    FutureTask<RealTimeRisk> result1=null;
                    FutureTask<RealTimeRisk> result2=null;
                    RealTimeRisk realTimeRisk=new RealTimeRisk();
                    RealTimeRisk realTimeRisk2=new RealTimeRisk();
                    long startTime=System.currentTimeMillis();
                    path=tempPath;//最初的dat路徑,上面進行過處理
                    int minVale=0;
                    int event=0;
                    int temp=0;
                    for (int i = 0; i < list.size(); i++) {
                        /**
                         * 目前發現5月份的dat和12月份的dat,兩個bpa手動快速點擊可以進行同時計算,但是最新的
                         * 12月份的兩個dat(修改過名稱),不能同時計算,目前沒有找到原因,因此多線程計算也會出現問題
                         * 暫時先注釋掉,還是先一個個計算,多線程需要修改i+=2
                         * BPA_EXE_PATH1=C:\\psap32\\BIN\\pfnt.exe
                         * BPA_EXE_PATH2=C:\\copypsap32\\psap32\\BIN\\pfnt.exe
                         */
//                        if(list.size()-i>=2){
//                            realTimeRiskCallable1= new RealTimeRiskCallable(path,1,Arrays.asList(list.get(i)));
//                            realTimeRiskCallable2= new RealTimeRiskCallable(path,2,Arrays.asList(list.get(i+1)));
//                            result1=new FutureTask<RealTimeRisk>(realTimeRiskCallable1);
//                            result2=new FutureTask<RealTimeRisk>(realTimeRiskCallable2);
//                            executorService.submit(result1);//Thread.sleep(5000);
//                            executorService.submit(result2);
//                            realTimeRisk=result1.get();//接收返回結果
//                            allResult.add(realTimeRisk);
//                            realTimeRisk2=result2.get();//接收返回結果
//                            allResult.add(realTimeRisk2);
//                        }else{
                            realTimeRiskCallable1= new RealTimeRiskCallable(path,1,Arrays.asList(list.get(i)));
                            result1=new FutureTask<RealTimeRisk>(realTimeRiskCallable1);
                            executorService.submit(result1);
                            realTimeRisk=result1.get();//接收返回結果
                            allResult.add(realTimeRisk);
//                        }
                        //獲取事故事件等級最低的(不為零,等級越低,事故事件等級越高)
                        event=Integer.parseInt(allResult.get(i).getAccidentEventRank());
                        if(event!=0){
                            if(temp==0){
                                minVale=event;
                                temp++;
                            }else{
                                if(event<minVale){
                                    minVale=event;
                                }
                            }
                        }
                    }
                    long endTime=System.currentTimeMillis();
                    logger.info("耗時:===>"+(endTime-startTime)/1000+"S");
                    logger.info("===>所有風險計算完成!共有:"+allResult.size()+"條風險記錄");

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM