实现多线程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