ProcessBuilder 프로 세 스 차단 문제

자바
Runtime.getInstance().exec (String cmd)
혹은
new ProcessBuilder(String cmd).start()
하위 프로 세 스 대상 Process 를 만 들 수 있 습 니 다.process 대상 을 호출 하 는 waitFor () 방법 을 통 해 메 인 프로 세 스 를 대기 상태 로 들 어가 하위 프로 세 스 가 실 행 될 때 까지 다음 작업 을 진행 할 수 있 습 니 다.하위 프로 세 스 를 잘못 처리 하면 메 인 프로 세 스 가 막 혀 프로그램 전체 가 죽 을 수 있 습 니 다.
자바 Api 에서 Process 에 대해 말 하 는 것 은:ProcessBuilder.start()  화해시키다  Runtime.exec  방법 은 이 컴퓨터 프로 세 스 를 만 들 고 되 돌려 줍 니 다.  Process  하위 클래스 의 인 스 턴 스 입 니 다. 이 인 스 턴 스 는 프로 세 스 를 제어 하고 관련 정 보 를 얻 을 수 있 습 니 다. Process  클래스 는 프로 세 스 입력, 출력 실행, 프로 세 스 완료 대기, 프로 세 스 종료 상태 검사 및 프로 세 스 를 없 애 는 방법 을 제공 합 니 다.
프로 세 스 를 만 드 는 방법 은 이 컴퓨터 플랫폼 의 특정 프로 세 스 를 잘 작 동 하지 못 할 수도 있 습 니 다. 예 를 들 어 이 컴퓨터 창 프로 세 스, 데 몬, Microsoft Windows 의 Win 16 / DOS 프로 세 스, 셸 스 크 립 트 등 입 니 다.만 든 하위 프로 세 스 는 터미널 이나 콘 솔 이 없습니다.모든 표준 io (즉 stdin, stdout, stderr) 작업 은 세 개의 흐름 getOutputStream(), getInputStream(), getErrorStream() 을 통 해 부모 프로 세 스 로 재 설정 합 니 다.부모 프로 세 스 는 이 흐름 을 사용 하여 하위 프로 세 스 의 입력 과 하위 프로 세 스에 서 출력 을 가 져 옵 니 다.일부 이 플랫폼 은 표준 입력 과 출력 흐름 에 만 제 한 된 버퍼 크기 를 제공 하기 때문에 읽 기 쓰기 서브 프로 세 스 의 출력 흐름 이나 입력 흐름 이 신속하게 실패 하면 서브 프로 세 스 가 막 히 고 심지어 잠 금 이 생 길 수 있 습 니 다.getOutputStream(), getInputStream(), getErrorStream() , : 출력 흐름 과 오류 흐름 을 버퍼 링 하 는 것 은 좋 은 생각 입 니 다!응, 추상 적 이 야!
문 제 는 바로 여기에 있 습 니 다. Process. getInputStream () 과 Process. getErrorStream () 은 각각 Process 의 표준 출력 흐름 과 오류 흐름 을 되 돌려 줍 니 다. 두 흐름 이 잘못 처리 되면 버퍼 가 제때에 제거 되 지 않 고 가득 차 면 프로 세 스 가 막 힙 니 다. Process. destory () 를 호출 하 더 라 도 막 힌 하위 프로 세 스 를 없 앨 수 있 는 것 은 아 닙 니 다.
Process 의 출력 흐름 과 오류 흐름 을 동기 화하 여 처리 하려 고 시도 하면 반드시 효과 가 있 는 것 은 아 닙 니 다. 순서 실행 과정 에서 출력 흐름 과 오류 흐름 은 제때에 처리 되 지 못 합 니 다.해결 방안 은 두 가지 가 있다.
프로젝트 1: process 의 출력 흐름 과 오류 흐름 을 동시에 가 져 옵 니 다.
두 스 레 드 를 시작 하여 출력 흐름 과 오류 흐름 을 동시에 읽 고 처리 합 니 다. IDE 를 열기 가 귀 찮 습 니 다. 코드 를 대충 두 드 려 보 세 요. 오류 가 있 을 수 있 습 니 다. 다음 과 같 습 니 다.
호출 자:
  • class ProcessExecutor  
  • {  
  •     private Process p;  
  •     private List outputList;  
  •     private List errorOutputList;  
  •     public ProcessExecutor(Process p) throws IOException  
  •     {  
  •         if(null == p)  
  •         {  
  •             throw new IOException("the provided Process is null");  
  •         }  
  •         this. p = p;  
  •     }  
  •     public List getOutputList()  
  •     {  
  •         return this. outputList;  
  •     }  
  •     public List getErrorOutputList()  
  •     {  
  •         return this.errorOutputList;  
  •     }  
  •     public int execute()  
  •     {  
  •         int rs = 0;  
  •         Thread outputThread = new ProcessOutputThread(this.p.getInputStream());  
  •         Thread errorOutputThread = new ProcessOutputThread(this.p.getErrorStream());  
  •         outputThread.start();  
  •         errorOutputThread.start();  
  •         rs = p.waitFor();  
  •         outputThread.join();  
  •         errorOutputThread.join();  
  •         this.outputList = outputThread.getOutputList();  
  •         this.errorOutputList = errorOutputThread.getOutputList();  
  •         return rs;  
  •     }  
  • }  

  • 흐름 처리 스 레 드
  • class ProcessOutputThread extends Thread  
  • {  
  •     private InputStream is;  
  •     private List outputList;  
  •     public ProcessOutputThread(InputStream is) throws IOException  
  •     {  
  •         if(null == is)  
  •         {  
  •             throw new IOException("the provided InputStream is null");  
  •         }  
  •         this. is = is;  
  •         this.outputList = new ArrayList();  
  •     }  
  •     public List getOutputList()  
  •     {  
  •         return this. outputList;  
  •     }  
  •     @Override  
  •     public void run()  
  •     {  
  •         InputStreamReader ir = null;  
  •         BufferedReader br = null;  
  •         try  
  •         {  
  •             ir = new InputStreamReader(this.is);  
  •             br = new BufferedReader(ir);  
  •             String output = null;  
  •             while(null != (output = br.readLine()))  
  •             {  
  •                 print(output);  
  •                 this.outputList.add(output);  
  •             }  
  •         }  
  •         catch(IOException e)  
  •         {  
  •             e.print();  
  •         }  
  •         finally  
  •         (  
  •             try  
  •             {  
  •                 if(null != br)  
  •                 {  
  •                     br.close();  
  •                 }  
  •                 if(null != ir)  
  •                 {  
  •                     ir.close();  
  •                 }  
  •                 if(null != this.is)  
  •                 {  
  •                     this.is.close();  
  •                 }  
  •             }  
  •             catch(IOException e)  
  •             {  
  •                 e.print();  
  •             }  
  •         )  
  •     }  
  • }  

  • 프로젝트 2: ProcessBuilder 의 redirect ErrorStream () 방법 으로 출력 흐름 과 오류 흐름 을 합 칩 니 다.
  • public int execute()  
  • {  
  •     int rs = 0;  
  •     String[] cmds = {...};//command and arg    
  •     ProcessBuilder builder = new ProcessBuilder(cmds);    
  •     builder.redirectErrorStream(true);    
  •     Process process = builder.start();    
  •     BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));    
  •     String output = null;    
  •     while (null != (readLine = br.readLine()))  
  •     {    
  •         print(output);     
  •     }    
  •     rs = process.waitFor();  
  •     return rs;  
  • }   
  • 좋은 웹페이지 즐겨찾기