VBScript에 대한 몇 가지 Runtime.exec()
호출을 통해 일부 외부 데이터를 검색 할 수밖에 없습니다. 크로스 플랫폼 유연성을 잃어 버렸기 때문에이 구현을 정말 싫어하지만 적어도 문제를 완화하기 위해 유사한 * nix 스크립트를 개발할 수 있습니다. 누구든지 묻기 전에 은이 내 데이터를 수집하기 위해 외부 스크립트를 호출 할 필요가 없도록 할 수 없습니다. 나는 그 원인으로 생겨날 것이다.Java - 여러 런타임 동시 런타임 문제 .exec() InputStreams
exec()
프로세스는 Runnable
까지 확장되는 사용자 정의 클래스에서 실행됩니다. BufferedReader
을 사용하여 getInputStream()
의 데이터를 읽습니다.
: 추가 코드가 요청 된대로 추가되었지만 추가 코드와의 관련성이 표시되지 않습니다. 포맷하는 데 시간이 걸렸기 때문에 도움이 되었기를 바랍니다. 그것은 추한하지만 건설적인 비판이 권장되는 경우 내가 개별적으로 명령을 실행하면 아, 그리고 예상대로 나는 데이터를 수집, ... 내 코드 스타일에
public class X extends JFrame implements Runnable {
...
static final int THREADS_MAX = 4;
ExecutorService exec;
...
public static void main(String[] args) {
...
SwingUtilities.invokeLater(new X("X"));
} // End main(String[])
public X (String title) {
...
exec = Executors.newFixedThreadPool(THREADS_MAX);
...
// Create all needed instances of Y
for (int i = 0; i < objects.length; i++) {
Y[i] = new Y(i);
} // End for(i)
// Initialization moved here for easy single-thread testing
// Undesired, of course
for (int i = 0; i < objects.length; i++) {
Y[i].initialize(parent);
} // End for(i)
} // End X
class Y implements Runnable {
// Define variables/arrays used to capture data here
String computerName = "";
...
public Y(int rowIndex) {
row = rowIndex;
...
computerName = (String)JTable.getValueAt(row, 0);
...
exec.execute(this);
} // End Y(int)
public void run() {
// Initialize variables/arrays used to capture data here
...
// Initialization should be done here for proper threading
//initialize(parent);
} // End run()
public void initialize(Z obj) {
runTime = Runtime.getRuntime();
...
try {
process = runTime.exec("cscript.exe query.vbs " + computerName);
stdErr = process.getErrorStream();
stdIn = process.getInputStream();
isrErr = new InputStreamReader(stdErr);
isrIn = new InputStreamReader(stdIn);
brErr = new BufferedReader(isrErr);
brIn = new BufferedReader(isrIn);
while ((line = brIn.readLine()) != null) {
// Capture, parse, and store data here
...
} // End while
} catch (IOException e) {
System.out.println("Unable to run script");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
stdErr.close();
stdIn. close();
isrErr.close();
isrIn. close();
brErr. close();
brIn. close();
} catch (IOException e) {
System.out.println("Unable to close streams.");
} // End try
} // End try
} // End initialize(Z)
...
} // End class Y
} // End class X
을 쉽게 이동합니다. 그러나 클래스의 run()
블록에서 명령을 실행하면 (예 : 호출이 동시에 발생 함을 의미 함) 모든 입력 스트림이 하나만 생성되는 것처럼 보입니다. 모두 BufferedReaders
이 동시에 소비됩니다.
문제를 디버깅하려면 입력 스트림을 읽는 클래스의 인스턴스가 접두사로 붙은 콘솔에서 각 사용 된 행을 출력합니다. 나는 그들이 인스턴스에 인스턴스의 순서가 될 수 있음을 이해하고, 다음과 같은 것을 기대하지만, 단일 인스턴스의 라인 순서는 그대로 다음과 같습니다
내가 예상 번호를 어떻게 이상한입니다exec 0: Line1
exec 1: Line1
exec 2: Line1
exec 0: Line2
exec 1: Line2
exec 2: Line2
exec 0: Line3
exec 1: Line3
exec 2: Line3
...
출력의 맨 처음 줄 (Microsoft (R) Windows Script Host Version 5.7
)의 인스턴스이지만이 행 다음에 입력 스트림에서 하나의 프로세스 만 계속 데이터를 생성하며 모든 판독기는 다음 예와 같이이 스트림을 임의로 소비합니다.
exec 2: Microsoft (R) Windows Script Host Version 5.7
exec 0: Microsoft (R) Windows Script Host Version 5.7
exec 1: Microsoft (R) Windows Script Host Version 5.7
exec 0: line2
exec 1: line3
exec 2: line4
...
설상가상으로 독자들은 실속하고 readLine()
은 null을 반환하지 않습니다. 이 유형의 동작에는 버퍼 크기와 관련이있을 수 있지만 짧은 출력에서도 두 개의 동시 스레드 만 실행하면 여전히 동일한 동작을 나타냅니다. stdErr
에 아무 것도 캡처되지 않아 문제가 있음을 나타냅니다.
이것이 스크립트 호스트의 제한 사항인지 확인하기 위해 START
스크립트의 여러 인스턴스를 동시에 배치하는 배치 파일을 만들었습니다. 이것은 cmd 쉘의 외부에서 Java의으로 실행되었다고 명시해야하며 자체 쉘을 여러 개 실행해야합니다. 그러나 각 동시 인스턴스는 예상 결과를 완전히 반환하고 올바르게 작동합니다.
편집 :
try {
Thread.sleep((int)(Math.random() * 1200));
} catch (InterruptedException e) {
System.out.println("Can't sleep!");
} // End try
initialize(monitor);
를 내 코드로 : 다른 문제 해결 아이디어로, 나는 동시성을 다시 활성화,하지만 내 Y.run()
블록에 다음을 삽입하여 내 초기화 방법을 비틀하기로 결정했다. 처음 몇 줄에 여러 개의 출력이 표시되기 시작하지만 동일한 제작자를 소비하는 여러 소비자로 신속하게 되돌아 가고 첫 번째 완성 된 스트림이 닫히 자마자 나머지 소비자는 예외를 발생시킵니다. 다음 소비자는 IOException: Read error
을 발사하고 나머지는 IOException: Stream closed
을 발사합니다!
는 maaartinus에 따르면, 이제 문제가 원하지 않는 행동의 원인이 무엇되고, 여러 실행하는 동시 InputStreams
수 있습니까? 어떻게 독립적으로 입력 스트림을 잡을 수 있습니까? 필자가 피할 수만 있다면 데이터를 다시 처리하기 위해 임시 파일에 기록하지 않아도됩니다.
는'그래서 혼란 스러워요? - 다중 입력을 처리 할 수있는 자바 동시에 여부 스트림입니다'확실히, 그것은이다. Windows Script Host에 문제가있을 수 있습니다. 사소한 출력을내는 사소한 스크립트 (또는 다른 프로그램)를 사용하려고합니다. – maaartinus
일부 필드가 정적 일 수 있으므로 이상하게 들립니다. 더 많은 수업을 게시 할 수 있습니까? 설상가상으로 –
'는 결코 즉, 두 개의 스레드 프로세스 당, 각 스트림에 대한 자신의 스레드를 사용해보십시오 null.' 반환, 독자는 실속 내의 readLine(). 각 스트림에는 작은 버퍼가 있으며 프로세스가 가득 차면 프로세스가 차단됩니다 (다른 스트림에서는 아무것도 얻지 못합니다). – maaartinus