1. 程式人生 > >java調Python指令碼(五):java通過 Runtime.getRuntime().exec()調Python指令碼一直沒有返回值,卡住了,資料太大

java調Python指令碼(五):java通過 Runtime.getRuntime().exec()調Python指令碼一直沒有返回值,卡住了,資料太大

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個執行緒分別跑錯誤流和資料返回流的處理: