In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "how to solve the waitFor deadlock problem of Process". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to solve the waitFor deadlock problem of Process.
Process's waitFor deadlock problem 1. Discovery problem
In the actual development, when carrying on the file operation, using Process to decompress the file, there will be the problem that it will be stuck there all the time in the process of program execution.
2. Reason finding
The problem is the buffer: the standard output of the executable program is more, while the standard buffer of the running window is not large enough, so blocking occurs. Next, to analyze the buffer, when the Runtime object calls exec (cmd), JVM starts a child process that establishes three pipeline connections to the JVM process: standard input, standard output, and standard error stream. Suppose the program is constantly writing data to the standard output stream and standard error stream, and if JVM does not read it, it will not be able to continue writing data when the buffer is full, resulting in blocking here in waitfor ().
The running process of the program produces waiting analysis:
When we use Runtime.exec to execute commands, the JAVA thread will create a child process to execute the command, and the child process and Java thread will run independently.
(2) the JAVA thread needs to wait for the completion of the execution of the command and process the log and return value of the command, so call Process.waitFor in the Java thread and wait for the child process to complete.
(3) when the child thread executes, the log information is constantly printed, and we obtain the normal output log and error log for processing through Process.getInputStream and Process.getErrorStream, that is, read the data.
(4) at this time, the child process keeps writing data to the JAVA thread, while the JAVA thread has been blocked and suspended after calling Process.waitFor, and the child process is constantly writing data to the JAVA thread. When our Process.getInputStream 's buffer buffer is full, the JAVA thread still hangs and does not consume the data in the buffer. As a result, the child process cannot continue to write data to the buffer buffer, causing the child process to hang.
(5), at this time, the JAVA thread and the child process are in a suspended state, the JAVA thread waits for the end of the child process, and the child process waits for the JAVA thread to consume the data in the Java buffer. The two are waiting for each other, resulting in a deadlock.
3. Deadlock schematic diagram
Problem code public static String cmd (String cmd) throws InterruptedException {try {/ / use Runtime to execute command and generate Process object Process process = Runtime.getRuntime () .exec (new String [] {"/ bin/sh", "- c", cmd}); int exitCode = process.waitFor () / / the output stream that gets the result of the command InputStream is = process.getInputStream (); / / reads InputStreamReader isr = new InputStreamReader (is) with a read output stream class; / / reads lines with buffer BufferedReader br = new BufferedReader (isr); String line = null StringBuilder sb = new StringBuilder (); while ((line = br.readLine ())! = null) {sb.append (line);} is.close (); isr.close (); br.close () Return sb.toString ();} catch (java.lang.NullPointerException e) {throw new BaseException (e);} catch (java.io.IOException e) {throw new BaseException (e);} return null;}
The reason why this code produces a deadlock is that BufferedReader br = new BufferedReader (isr); is placed on process.waitFor (); and then executes, which does not effectively empty the buffer, or causes the buffer to be full and cause blocking.
Solution
If you know the cause of the problem, it will be solved.
Public static String callCmd (String cmd) throws InterruptedException {Process process = null; BufferedReader normalReader = null; BufferedReader errorReader = null; try {process = Runtime.getRuntime () .exec (new String [] {"/ bin/sh", "- c", cmd}) / * start the child thread reading the buffer buffer to prevent the buffer buffer from being full, resulting in thread waiting problems * / normalReader = new BufferedReader (new InputStreamReader (process.getInputStream (); errorReader = new BufferedReader (new InputStreamReader (process.getErrorStream (); String line = null StringBuilder sb = new StringBuilder (); while ((line = normalReader.readLine ())! = null) {sb.append (line);} String errorLine While ((errorLine = errorReader.readLine ())! = null) {logger.warn ("script file execution information ErrorStream: {}", errorLine);} / / wait for program execution to finish and output status int exitCode = process.waitFor () If (0 = = exitCode) {logger.info ("script file execution succeeded!");} else {logger.error ("script file execution failed: {}", cmd); throw new BaseException ("script file execution failed:" + cmd) } return sb.toString ();} catch (java.lang.NullPointerException e) {throw new BaseException (e);} catch (java.io.IOException e) {throw new BaseException (e) } finally {if (null! = normalReader) {try {normalReader.close ();} catch (IOException e) {logger.error ("streaming file close exception:", e) }} if (null! = errorReader) {try {errorReader.close ();} catch (IOException e) {logger.error ("streaming file close exception:", e) A simple example of deadlock in}} if (null! = process) {process.destroy ();} Java and its avoidance
Deadlock: when a thread holds a lock forever and other threads try to acquire the lock, they will always be blocked.
For example, if thread 1 already holds the A lock and wants to acquire the B lock, while thread 2 holds the B lock and tries to acquire the A lock, the two threads will wait forever.
Let's look at a simple example of a deadlock public class DeadLockTest {private static Object A = new Object (), B = new Object (); public static void main (String [] args) {new Thread (()-> {System.out.println ("Thread 1 starts execution.") Synchronized (A) {try {System.out.println ("Thread 1 gets the A lock"); / / dormant for two seconds to allow thread 2 time to get the B lock Thread.sleep (2000) } catch (Exception e) {e.printStackTrace ();} synchronized (B) {System.out.println ("Thread 1 gets the B lock");}. Start () New Thread (()-> {System.out.println ("Thread 2 starts execution..."); synchronized (B) {try {System.out.println ("Thread 2 gets the B lock") / / dormant for two seconds to allow thread 1 time to get the A lock Thread.sleep (2000);} catch (Exception e) {e.printStackTrace () } synchronized (A) {System.out.println ("Thread 2 gets lock A");}) .start ();}}
Running result:
As can be seen from the running results, thread 1 got the A lock and tried to acquire the B lock, while thread 2 got the B lock and tried to acquire the A lock, and thread 1 and thread 2 fell into an infinite wait, forming a deadlock.
So how to prevent deadlocks? Here are a few common methods:
1. Avoid one thread acquiring multiple locks at the same time
2. Avoid a thread occupying multiple resources in the lock at the same time, and try to ensure that each lock occupies only one resource.
3. Try to use a timing lock and use lock.tryLock instead of a built-in lock.
At this point, I believe you have a deeper understanding of "how to solve the waitFor deadlock problem of Process". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue 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.