Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java ProcessBuilder未关闭_Java_Multithreading_Processbuilder - Fatal编程技术网

Java ProcessBuilder未关闭

Java ProcessBuilder未关闭,java,multithreading,processbuilder,Java,Multithreading,Processbuilder,我已经尝试了现有线程中提供的所有选项,如,和 我将有100个资源密集型命令,每个命令的运行时间从几分钟到4-5小时不等。我希望最多有5个并发线程来执行这些命令 现在,我正在Windows上的10个mkdir命令上试用该代码。输出是正确的,我没有得到任何异常,但是,10进程没有终止 一个命令,例如: "testthread1"~mkdir "E:\\Omkar\\Development\\Files\\java\\testthread1" 这条路是可以走的。请注意,process.waitFor

我已经尝试了现有线程中提供的所有选项,如,和

我将有100个资源密集型命令,每个命令的运行时间从几分钟到4-5小时不等。我希望最多有5个并发线程来执行这些命令

现在,我正在Windows上的10个mkdir命令上试用该代码。输出是正确的,我没有得到任何异常,但是,10进程没有终止

一个命令,例如:

"testthread1"~mkdir "E:\\Omkar\\Development\\Files\\java\\testthread1"
这条路是可以走的。请注意,process.waitFor()在finally块中被注释为(我也在start()之后的try块中尝试了它,但问题相同),如果我使用它,则只会创建5个目录:

public class CommandRunner implements Runnable {

    private static final Logger logger = LogManager
            .getLogger(CommandRunner.class);

    private String command;
    private boolean isRemoteExecution = false;
    private Properties configurations;
    private String commandReferenceName;

    public CommandRunner(String command, boolean isRemoteExecution,
            Properties configurations, String commandReferenceName) {
        super();
        this.command = command;
        this.isRemoteExecution = isRemoteExecution;
        this.configurations = configurations;
        this.commandReferenceName = commandReferenceName;

    }

    @Override
    public void run() {
        // TODO Auto-generated method stub

        if (isRemoteExecution) {

            executeCommandRemotely();
        } else {
            executeCommandLocally();
        }
    }

    private void executeCommandRemotely() {

    }

    private void executeCommandLocally() {

        ProcessBuilder processBuilder = getProcessBuilder(command);
        Process process = null;

        try {

            logger.debug("Starting " + commandReferenceName);

            process = processBuilder.start();
            // int errCode = process.waitFor();
            //
            // logger.debug("Executed ", this, " errors ? ", (errCode == 0 ?
            // "No"
            // : "Yes"));
            //
            printInputStreamTraditionalWay(process.getInputStream());

        } catch (IOException e) {
            // TODO Auto-generated catch block
            logger.error("IOException", e);
        } finally {
            logger.debug("finally block for thread " + commandReferenceName);
            try {
                //process.waitFor();
                process.getInputStream().close();
                process.getOutputStream().flush();
                process.getOutputStream().close();
                process.getErrorStream().close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                logger.error("IOException in finally block", e);
            }

        }

    }

    private void printInputStreamTraditionalWay(InputStream inputStream) {

        byte[] byteArray = new byte[1024];

        try {
            while (inputStream.available() != 0) {
                inputStream.read(byteArray);
                logger.debug(new String(byteArray));
            }

            logger.debug("Input stream consumed, returning !");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            logger.error(
                    "IOException while reading Process input stream TraditionalWay!",
                    e);
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                logger.error(
                        "IOException while closing Process input stream TraditionalWay!",
                        e);
            }
        }
    }

    private void printInputStreamBufferedWay(InputStream inputStream) {
        // TODO Auto-generated method stub
        BufferedReader br = null;

        br = new BufferedReader(new InputStreamReader(inputStream));
        String line = null;

        try {
            while ((line = br.readLine()) != null) {

                logger.debug(line + System.getProperty("line.separator"));

            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            logger.error(
                    "IOException while reading Process input stream BufferedWay!",
                    e);
        } finally {
            try {
                br.close();
                inputStream.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                logger.error(
                        "IOException while closing Process input stream BufferedWay!",
                        e);
            }

        }

    }

    private ProcessBuilder getProcessBuilder(String command) {
        // TODO Auto-generated method stub
        String operSys = System.getProperty("os.name").toLowerCase();
        String shell = null;
        String executeCommandOption = null;

        if (operSys.contains("win")) {
            shell = configurations.getProperty(Constants.WINDOWS_SHELL);
            executeCommandOption = configurations
                    .getProperty(Constants.WINDOWS_EXEC_OPTION);
        } else if (operSys.contains("nix") || operSys.contains("nux")
                || operSys.contains("aix")) {
            shell = configurations.getProperty(Constants.LINUX_SHELL_1);
            executeCommandOption = configurations
                    .getProperty(Constants.LINUX_EXEC_OPTION_1);
        } else if (operSys.contains("mac")) {

        } else if (operSys.contains("sunos")) {

        }

        ProcessBuilder processBuilder = new ProcessBuilder(shell,
                executeCommandOption, command);

        processBuilder.redirectErrorStream(true);
        processBuilder.inheritIO();

        return processBuilder;
    }

    public boolean isRemoteExecution() {
        return isRemoteExecution;
    }

    public void setRemoteExecution(boolean isRemoteExecution) {
        this.isRemoteExecution = isRemoteExecution;
    }

    public String getCommand() {
        return command;
    }

    public void setCommand(String command) {
        this.command = command;
    }

    @Override
    public String toString() {
        return "CommandRunner [commandReferenceName=" + commandReferenceName
                + "]";
    }

}
向执行器提交线程的主类:

public class CommandExecutor {

    private static final Logger logger = LogManager
            .getLogger(CommandExecutor.class);

    private static final int argsCount = 2;

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        if (args == null || args.length < argsCount) {
            logger.error("Please provide params as follows : \n <config.-properties-file-name> : The absolute properties file path where the config. is stored \n <commands-file-name> : The absolute file path where the commands are stored with one command per line");
            return;
        }

        new CommandExecutor().executeCommandsInParallel(args[0], args[1]);
    }

    private void executeCommandsInParallel(
            String configPropertiesFileAbsolutePath,
            String commandFileAbsolutePath) {

        /* MethodCall : Validate paths */

        /* MethodCall : Load configurations */
        Properties configurations = null;
        try {
            configurations = getConfiguration(configPropertiesFileAbsolutePath);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        /* MethodCall : Read the commands from the file in a Collection<String> */
        Collection<String> commands = null;
        try {
            commands = getCommands(commandFileAbsolutePath);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        /* Start reading the commands and scheduling them */
        if (commands != null && !commands.isEmpty()) {

            ScheduledThreadPoolExecutor threadPoolExecutor = new ScheduledThreadPoolExecutor(
                    Integer.valueOf(configurations
                            .getProperty(Constants.SQOOP_IMPORT_CONCURRENCY_FACTOR)));
            threadPoolExecutor
                    .setMaximumPoolSize(Integer.valueOf(configurations
                            .getProperty(Constants.SQOOP_IMPORT_CONCURRENCY_FACTOR)));

            Collection<Future> submittedCommandsFuture = new ArrayList<Future>();

            for (String commandString : commands) {

                String commandStringArray[] = commandString
                        .split(configurations
                                .getProperty(Constants.SPLIT_COMMAND_NAME_BY));

                CommandRunner commandRunner = new CommandRunner(
                        commandStringArray[1], Boolean.valueOf(configurations
                                .getProperty(Constants.IS_REMOTE_EXECUTION)),
                        configurations, commandStringArray[0]);

                logger.debug("Submitting " + commandStringArray[0]
                        + " for execution");

                Future commandRunnerFuture = threadPoolExecutor
                        .submit(commandRunner);
                submittedCommandsFuture.add(commandRunnerFuture);

                //printThreadPoolStats(threadPoolExecutor);
            }

        } else {
            System.out.println("No commands found, returning !");
            return;
        }

    }

    private Properties getConfiguration(String configPropertiesFileAbsolutePath)
            throws IOException {

        Properties configuration = new Properties();

        configuration.load(Files.newInputStream(FileSystems.getDefault()
                .getPath(configPropertiesFileAbsolutePath)));

        return configuration;

    }

    private Collection<String> getCommands(String commandFileAbsolutePath)
            throws IOException {

        List<String> commands = null;

        Path commandFilePath = FileSystems.getDefault().getPath(
                commandFileAbsolutePath);
        commands = Files.readAllLines(commandFilePath);

        return commands;
    }

    private void printThreadPoolStats(ThreadPoolExecutor poolExecutor) {
        logger.debug("Active tasks : " + poolExecutor.getActiveCount()
                + "Completed tasks : " + poolExecutor.getCompletedTaskCount()
                + "Pool size : " + poolExecutor.getPoolSize()
                + "Scheduled Tasks : " + poolExecutor.getTaskCount());
    }

    static class CustomThreadFactory implements ThreadFactory {
        private static final AtomicInteger poolNumber = new AtomicInteger(1);
        private final ThreadGroup group;
        private final AtomicInteger threadNumber = new AtomicInteger(1);
        private final String namePrefix;

        CustomThreadFactory(String factoryName) {
            SecurityManager s = System.getSecurityManager();
            group = (s != null) ? s.getThreadGroup() : Thread.currentThread()
                    .getThreadGroup();
            namePrefix = factoryName + poolNumber.getAndIncrement()
                    + "-thread-";
        }

        public Thread newThread(Runnable r) {
            Thread t = new Thread(group, r, namePrefix
                    + threadNumber.getAndIncrement(), 0);
            if (t.isDaemon())
                t.setDaemon(false);
            if (t.getPriority() != Thread.NORM_PRIORITY)
                t.setPriority(Thread.NORM_PRIORITY);
            return t;
        }
    }
}

必须调用Procces.destroy()才能杀死它。例如,您可以注册shutdownhook来完成此操作,我没有看到ProcessBuilder的命令参数。例如,
mkdir
应该是
newprocessbuilder(“mkdir”、“foo”)
创建目录
foo
而不是
newprocessbuilder(“mkdir foo”)。这一点很重要,因为这样做的结果类似于未找到
命令mkdir foo
。请创建一个,因为代码太多,无法轻松调试。此外,我们没有看到您发送给process builder的实际命令,这对于了解问题非常重要
表示子进程将使用父进程的
stdin
stdout
,而不是通过管道进行通信。如果您使用它,那么从创建的
进程访问流就没有意义了。
@Holger是的,我知道,我只是在引用现有线程后添加了那段代码,但是,这似乎没有什么区别
[DEBUG] 2016-08-22 16:55:37.176 [main] CommandExecutor - Submitting "testthread1" for execution
[DEBUG] 2016-08-22 16:55:37.178 [main] CommandExecutor - Submitting "testthread2" for execution
[DEBUG] 2016-08-22 16:55:37.178 [main] CommandExecutor - Submitting "testthread3" for execution
[DEBUG] 2016-08-22 16:55:37.178 [main] CommandExecutor - Submitting "testthread4" for execution
[DEBUG] 2016-08-22 16:55:37.178 [pool-2-thread-1] CommandRunner - Starting "testthread1"
[DEBUG] 2016-08-22 16:55:37.179 [main] CommandExecutor - Submitting "testthread5" for execution
[DEBUG] 2016-08-22 16:55:37.179 [pool-2-thread-3] CommandRunner - Starting "testthread3"
[DEBUG] 2016-08-22 16:55:37.178 [pool-2-thread-2] CommandRunner - Starting "testthread2"
[DEBUG] 2016-08-22 16:55:37.179 [pool-2-thread-4] CommandRunner - Starting "testthread4"
[DEBUG] 2016-08-22 16:55:37.179 [main] CommandExecutor - Submitting "testthread6" for execution
[DEBUG] 2016-08-22 16:55:37.179 [main] CommandExecutor - Submitting "testthread7" for execution
[DEBUG] 2016-08-22 16:55:37.179 [main] CommandExecutor - Submitting "testthread8" for execution
[DEBUG] 2016-08-22 16:55:37.179 [pool-2-thread-5] CommandRunner - Starting "testthread5"
[DEBUG] 2016-08-22 16:55:37.179 [main] CommandExecutor - Submitting "testthread9" for execution
[DEBUG] 2016-08-22 16:55:37.181 [pool-2-thread-4] CommandRunner - Input stream consumed, returning !
[DEBUG] 2016-08-22 16:55:37.181 [pool-2-thread-4] CommandRunner - finally block for thread "testthread4"
[DEBUG] 2016-08-22 16:55:37.181 [pool-2-thread-4] CommandRunner - Starting "testthread6"
[DEBUG] 2016-08-22 16:55:37.182 [pool-2-thread-5] CommandRunner - Input stream consumed, returning !
[DEBUG] 2016-08-22 16:55:37.182 [pool-2-thread-5] CommandRunner - finally block for thread "testthread5"
[DEBUG] 2016-08-22 16:55:37.182 [pool-2-thread-5] CommandRunner - Starting "testthread7"
[DEBUG] 2016-08-22 16:55:37.184 [pool-2-thread-3] CommandRunner - Input stream consumed, returning !
[DEBUG] 2016-08-22 16:55:37.184 [pool-2-thread-3] CommandRunner - finally block for thread "testthread3"
[DEBUG] 2016-08-22 16:55:37.184 [pool-2-thread-3] CommandRunner - Starting "testthread8"
[DEBUG] 2016-08-22 16:55:37.186 [pool-2-thread-1] CommandRunner - Input stream consumed, returning !
[DEBUG] 2016-08-22 16:55:37.186 [pool-2-thread-1] CommandRunner - finally block for thread "testthread1"
[DEBUG] 2016-08-22 16:55:37.186 [pool-2-thread-1] CommandRunner - Starting "testthread9"
[DEBUG] 2016-08-22 16:55:37.187 [pool-2-thread-2] CommandRunner - Input stream consumed, returning !
[DEBUG] 2016-08-22 16:55:37.187 [pool-2-thread-2] CommandRunner - finally block for thread "testthread2"
[DEBUG] 2016-08-22 16:55:37.189 [pool-2-thread-1] CommandRunner - Input stream consumed, returning !
[DEBUG] 2016-08-22 16:55:37.189 [pool-2-thread-1] CommandRunner - finally block for thread "testthread9"
[DEBUG] 2016-08-22 16:55:37.191 [pool-2-thread-3] CommandRunner - Input stream consumed, returning !
[DEBUG] 2016-08-22 16:55:37.191 [pool-2-thread-3] CommandRunner - finally block for thread "testthread8"
[DEBUG] 2016-08-22 16:55:37.192 [pool-2-thread-5] CommandRunner - Input stream consumed, returning !
[DEBUG] 2016-08-22 16:55:37.193 [pool-2-thread-5] CommandRunner - finally block for thread "testthread7"
[DEBUG] 2016-08-22 16:55:37.194 [pool-2-thread-4] CommandRunner - Input stream consumed, returning !
[DEBUG] 2016-08-22 16:55:37.194 [pool-2-thread-4] CommandRunner - finally block for thread "testthread6"

E:\Omkar\Development\Directories\Workspaces\Tech\Homework\16032016\Scratchpad>
E:\Omkar\Development\Directories\Workspaces\Tech\Homework\16032016\Scratchpad>
E:\Omkar\Development\Directories\Workspaces\Tech\Homework\16032016\Scratchpad>
E:\Omkar\Development\Directories\Workspaces\Tech\Homework\16032016\Scratchpad>
E:\Omkar\Development\Directories\Workspaces\Tech\Homework\16032016\Scratchpad>
E:\Omkar\Development\Directories\Workspaces\Tech\Homework\16032016\Scratchpad>
E:\Omkar\Development\Directories\Workspaces\Tech\Homework\16032016\Scratchpad>
E:\Omkar\Development\Directories\Workspaces\Tech\Homework\16032016\Scratchpad>
E:\Omkar\Development\Directories\Workspaces\Tech\Homework\16032016\Scratchpad>