java調Python指令碼(五):java通過 Runtime.getRuntime().exec()調Python指令碼一直沒有返回值,卡住了,資料太大
阿新 • • 發佈:2018-12-03
1、背景:
當我們呼叫系統外部的某個程式,此時就可以用Runtime.getRuntime().exec()來呼叫。這次java調Python演算法程式碼時,一直沒有返回值,卡住了,而用pycharm跑Python程式碼是正常的,說明是java這邊的問題。去看了後臺的java程序一直都在,掛住了,找了好久才想到是阻塞問題, 原來是因為Python檔案中返回的資料太大而且很多,況且Python執行中出現很多異常警告和提示什麼的都是輸出控制檯,所以不及時捕捉程序的輸出,程序就被掛起了。
解決:啟動Process 程序後,再啟動兩個JAVA執行緒各種型別是資料流及時的把被呼叫程序的輸出截獲,完美ok解決。
2、程式碼實現用執行緒對資料流的處理類:
/** * * 處理流執行緒 * * @version 1.0 * @since JDK1.8 * @author weijs * @date 2018年9月28日 下午1:31:59 */ public class StreamThread extends Thread { private Logger logger = Logger.getLogger(getClass()); // 輸入流 private InputStream inputStream; // 流型別 private String streamType; // 是否執行完成 private volatile boolean inFinish = false; // 需要的返回結果資料 private Map<String, JSONArray> resultMap; /** * 構造器 * * @param inputStream 輸入流 * @param streamType 流型別 */ public StreamThread(InputStream inputStream, String streamType) { this.inputStream = inputStream; this.streamType = streamType; this.inFinish = false; this.resultMap = new HashMap<>(); } /** * 重寫run()方法 */ public void run() { try { InputStreamReader isr = new InputStreamReader(inputStream, "GBK"); BufferedReader bufferedReader = new BufferedReader(isr); String line; while ((line = bufferedReader.readLine()) != null) { if (streamType.equals("Error")) { logger.error(">>>>>>Error :" + line); } else { logger.info("info:" + line); if (line.contains("[{")) {// Python返回的json資料 logger.debug("---------最想要的結果:" + line); if (line.contains("back_result:")) { String back = line.substring(line.indexOf("[{"), line.length()); JSONArray fromObject = JSONObject.parseArray(back); resultMap.put("back", fromObject); } if (line.contains("filter_result:")) { String string = line.substring(line.indexOf("[{"), line.length()); JSONArray fromObject = JSONObject.parseArray(string); resultMap.put("filter", fromObject); } if (line.contains("buy_result:")) { String string = line.substring(line.indexOf("[{"), line.length()); JSONArray fromObject = JSONObject.parseArray(string); resultMap.put("buy", fromObject); } } } } isr.close(); bufferedReader.close(); } catch (IOException e) { logger.error("Exception:" + e); e.printStackTrace(); } finally { this.inFinish = true; synchronized (this) { notify(); } } } /** * * 返回結果 * * @return * * @author weijs * @date 2018年9月28日 下午1:37:42 */ public Map<String, JSONArray> getContent() { if (!this.inFinish) { synchronized (this) { try { wait(); } catch (InterruptedException ignore) { ignore.printStackTrace(); } } } return this.resultMap; } }
3、開啟2個執行緒分別跑錯誤流和資料返回流的處理: