In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces how to solve the problem of blocking based on Process#waitFor (). It has a certain reference value. Interested friends can refer to it. I hope you will gain a lot after reading this article. Let's take a look at it.
Process#waitFor () blocking problem
Sometimes you need to call an executable program or script command in a program:
Process process = Runtime.getRuntime () .exec (shPath); int exitCode = process .waitFor ()
Runtime.getRuntime () returns the Runtime object of the current application, whose exec () method instructs the Java virtual machine to create a child process to execute the specified executable and return an instance of the Process object corresponding to that child process. Through Process, you can control the execution of the child process or obtain the information of the child process.
All of its standard io (that is, stdin,stdout,stderr) operations are redirected to the parent process through three streams (getOutputStream (), getInputStream (), getErrorStream ()). The parent process uses these streams to provide input to and obtain output from the child process. Because the input and output streams provide a limited buffer size, if the output stream or input stream of the read-write child process fails, and the data can no longer be written when the buffer is full, it may cause the child process to block and eventually block here in waifor ().
In this case, the solution is to clear the getInputStream () and getErrorStream () streams. And the emptying of the two streams must be asynchronous.
Static void drainInBackground (final InputStream is) {new Thread (new Runnable () {public void run () {try {while (is.read () > = 0)) } catch (IOException e) {/ / return on IOException}. Start ();}
Another solution is to use ProcessBuilder to create Process objects, and you must use the redirectErrorStream method of ProcessBuilder. When the redirectErrorStream method is set to ture, the two streams getInputStream () and getErrorStream () will be merged, automatically emptying the stream without having to handle it yourself. If the two streams of false,getInputStream () and getErrorStream () are separated, they must be handled by themselves. The procedure is as follows:
Try {ProcessBuilder pbuilder=new ProcessBuilder ("ping", "192.168.0.125"); pbuilder.redirectErrorStream (true); process=pbuilder.start (); reader=new BufferedReader (new InputStreamReader (process.getInputStream (); String line=null; while ((line=reader.readLine ())! = null) {System.out.println (line) } int result=process.waitFor (); System.out.println (result);} catch (IOException e) {/ / TODO Auto-generated catch block e.printStackTrace ();} catch (InterruptedException e) {/ / TODO Auto-generated catch block e.printStackTrace ();} Process process = null Try {process = launchProcess (cmdlist, environment); StringBuilder sb = new StringBuilder (); String output = getOutput (process.getInputStream ()); String errorOutput = getOutput (process.getErrorStream ()); sb.append (output); sb.append ("\ n"); sb.append (errorOutput) Boolean ret = process.waitFor (1L, TimeUnit.SECONDS); if (! ret) {System.out.println (command + "is terminated abnormally. Ret= {}, str= {} "+ ret +" + sb.toString ();} return sb.toString ();} catch (Throwable e) {System.out.println ("Failed to run" + command + ","); e.printStackTrace () } finally {if (null! = process) {process.destroy ();}} return ""
Note that process must be released
Process.waitFor () causes the main thread to block
When developing today, use the runtime variable RunTime.getRunTime () that comes with jdk to execute the bash command.
Because this bash operation takes a long time, Process.waitFor () is used to wait for the child thread to finish running.
At this time, it is found that the program card does not continue to execute in waitFor ().
Read the official explanation:
WaitFor: this method returns immediately when the execution of the child process ends, or the child process has been terminated.
When the exec method is called by the RunTime object, jvm creates a child process that establishes three pipeline connections to jvm: standard input stream, standard output stream, and standard error stream. Suppose that the child process keeps writing data to the standard input stream and the standard output stream, and if jvm does not read it, it will cause the buffer to fill up and cannot continue to write data, eventually blocking the waitFor.
Knowing the problem is easy to deal with, we only need to read the information returned by the child process from the buffer to avoid the main thread blocking problem.
Public static void main (String [] args) {Process proc = RunTime.getRunTime (). Exec ("sh / home/winnie/dataExtract.sh") / / Standard input stream (must be written before waitFor) String inStr = consumeInputStream (proc.getInputStream ()); / / Standard error stream (must be written before waitFor) String errStr = consumeInputStream (proc.getErrorStream ()); int retCode = proc.waitFor () If (retCode = = 0) {System.out.println ("Program ends normally");}} / * consume inputstream and return * / public static String consumeInputStream (InputStream is) {BufferedReader br = new BufferedReader (new InputStreamReader (is)); String s; StringBuilder sb = new StringBuilder (); while ((s=br.readLine ())! = null) {System.out.println (s); sb.append (s) } return sb.toString ();} Thank you for reading this article carefully. I hope the article "how to solve the congestion problem based on Process#waitFor ()" shared by the editor will be helpful to you. At the same time, I also hope you will support us and pay attention to the industry information channel. More related knowledge is waiting for you to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.