栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java调用python脚本,BufferedReader的readline函数无任何输出结果,进程长时间卡住

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java调用python脚本,BufferedReader的readline函数无任何输出结果,进程长时间卡住

Java调用python脚本,BufferedReader的readline函数无任何输出结果,进程长时间卡住
    • 问题1 Java调用python返回值一直为null
    • 问题2 BufferedReader的readline函数无任何输出结果,进程长时间卡住

最近在做项目时,需要用到Java调用python文件并读取运行结果。一般Java调用简单的Python文件(不包含第三方库的)是没有任何问题的,但是我需要用到tensorflow、keras、numpy等第三方库,所以遇到了很多麻烦,经过各种百度查找,最终解决了问题,在这里做一个总结归纳。

问题1 Java调用python返回值一直为null

这个问题是我没有创建虚拟环境造成的,因为自己电脑上用的一直是Anaconda安装时自带的python,没有创建自己的虚拟环境,因此在Java中调用python文件时,就会找不到各种第三方库的问题。

问题2 BufferedReader的readline函数无任何输出结果,进程长时间卡住

这个问题我也找了很多方法才解决,产生这个问题的主要原因是:
命令在运行的过程中会向标准输出或者标准错误输出写出数据,但JVM又没有去读,导致缓冲区满,进而导致进程阻塞。因为我的python文件调用的tensorflow,他会输出一堆警告信息,这些警告信息属于错误流(ErrorStream),如果我们没有及时处理,就会导致缓冲区占满,从而导致进程阻塞。

Process.getInputStream()和Process.getErrorStream()分别返回Process的标准输出流和错误流,两个流如果处理不当,其缓冲区不能被及时清除而被塞满,则进程被阻塞,即使调用Process.destory()也未必能销毁被阻塞的子进程。

这个问题的解决的方法比较简单,既然问题是缓冲区满之后没有及时清理,那么只要在Java代码里去读一下数据,保证缓冲区不会满即可.
具体代码如下:

public static void main(String[] args) {
        try{
            System.out.println("start");
            //一定要用虚拟环境下的python路径
            String[] args1=new String[]{"D:\SoftWare\Anaconda\envs\jst\python.exe","F:\Python_Project\test.py"};
            Process pr = Runtime.getRuntime().exec(args1);

            // 防止缓冲区满, 导致卡住
            new Thread() {
                @Override
                public void run() {
                    super.run();
                    String line;
                    try {
                        BufferedReader stderr = new BufferedReader(new InputStreamReader(pr.getErrorStream(),"GBK"));
                        while ((line = stderr.readLine()) != null) {
                            System.out.println("stderr:" + line);
                        }
                    }
                    catch (Exception e) {

                    }

                }
            }.start();

            System.out.println("==============打印结果==============");
            new Thread() {
                @Override
                public void run() {
                    super.run();
                    String line;
                    try {
                        BufferedReader stdout = new BufferedReader(new InputStreamReader(pr.getInputStream(),"GBK"));
                        while ((line = stdout.readLine()) != null) {
                            System.out.println("stdout:" + line);
                        }
                    }
                    catch (Exception e) {

                    }
                }
            }.start();

            int exitVal = pr.waitFor();
            if (0 != exitVal) {
                System.out.println("执行脚本失败");
            }
            System.out.println("执行脚本成功");



        } catch (Exception e){
            e.printStackTrace();
        }
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/458859.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号