最近在java代碼中使用runtime.exec執(zhí)行rsync命令做同步,發(fā)現(xiàn)當(dāng)兩個目錄需要非常大同步工作的時候,rsync進程就
會一直阻塞。查看了jdk幫助,以及google都無果,于是打算把執(zhí)行的信息都log出來,結(jié)果執(zhí)行突然成功。仔細思考,這個問題應(yīng)該是進程執(zhí)行命令的
時候,輸出結(jié)果有個buffer,如果buffer已經(jīng)滿了,而沒有進程去讀,這個進程就會阻塞等待,導(dǎo)致我前面的問題出現(xiàn)。
效果可以通過如下代碼說明:
- import java.io.*;
-
- public class Rsync{
- public static void main(String[] args) throws Exception{
- if(args.length != 2){
- System.out.println("Usage: java Rsync src des");
- return;
- }
- Process proc = Runtime.getRuntime().exec("rsync -v -r -e --progress ssh -t -C " + args[0] + " " + args[1]);
- System.out.println("Waiting for end...");
- BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
- String line = null;
- while((line = br.readLine()) != null){
- System.out.println(line);
- }
- br.close();
- int exitValue = 0;
- if((exitValue = proc.waitFor()) != 0){
- System.out.println("exitValue:" + exitValue);
- }
- System.out.println("rsync complete!");
- }
- }
import java.io.*;
public class Rsync{
public static void main(String[] args) throws Exception{
if(args.length != 2){
System.out.println("Usage: java Rsync src des");
return;
}
Process proc = Runtime.getRuntime().exec("rsync -v -r -e --progress ssh -t -C " + args[0] + " " + args[1]);
System.out.println("Waiting for end...");
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while((line = br.readLine()) != null){
System.out.println(line);
}
br.close();
int exitValue = 0;
if((exitValue = proc.waitFor()) != 0){
System.out.println("exitValue:" + exitValue);
}
System.out.println("rsync complete!");
}
}
如果注釋掉:
- BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
- String line = null;
- while((line = br.readLine()) != null){
- System.out.println(line);
- }
- br.close();
BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = null;
while((line = br.readLine()) != null){
System.out.println(line);
}
br.close();
在兩個目錄需要大量的同步操作時就會一直blocked住。
所以如果你不需要執(zhí)行命令的輸出,最好直接將輸出重定向到 > /dev/nll