2014-12-03 4 views
0

현재, 나는 별도의 Java 프로그램을 여러 번 실행해야하지만 다른 매개 변수를 사용하여 programm를 작성하려고합니다. 이 실행 된 Java 프로그램은 Thread-Class를 호출합니다. 이 클래스 내에서 (게임) 서버에 대한 연결이 설정됩니다. 연결되면 스레드는 연결된 플레이어를 10 밀리 초마다 돌리는 명령을 보냅니다.자바 멀티 스레딩 : 어떻게 스레드를 실행하고있는 외부 Java 프로그램을 시작할 수 있습니까?

쉬운 일 (일) : 실제로이 제대로 작동

public class GeneralAgentTest { 

public static void main(String [] args){ 

    Thread thread = new Thread(new HexagonRunner("127.0.0.1",6000,"UnitedTestors",-30,-15)); 
    thread.start(); 
} 
} 

,하지만 내 목표 나는이 2 "솔루션"을 가지고있다. 이 스레드 (새로운 스레드 (새로운 HexagonRunner ("127.0.0.1", 6000, "UnitedTestors", - 30, -15))를 여러 개 시작해야하며 각 스레드는 별도의 프로세스로 처리해야합니다.

이렇게하려면 ProcessBuilder를 사용하여 코드를 작성했습니다. 이것은 한 클래스 안에 있습니다. 제대로 하나를 작동하지

둘째 :

public void execute(Class class1, int a, String str, String team, String x, 
     String y) { 

    ProcessBuilder builder; 
    String javaHome = System.getProperty("java.home"); 
    String javaBin = javaHome + File.separator + "bin" + File.separator 
      + "java"; 
    String classpath = System.getProperty("java.class.path"); 
    String className = class1.getCanonicalName(); 

    builder = new ProcessBuilder(javaBin, "-cp", classpath, 
      className, ip, port, team, str, x, y); 

    try { 
     process[a] = builder.start(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     System.out.println("failed"); 
    } 

public void loadPlayers() { 
    process = new Process[4]; 
    for (int i = 0; i < 4; i++) { 
     try { 
      execute(processes.StartProcesses.class, i, 
        playerCombo[i].getSelectedItem().toString(), 
        playerTeam[i].getText(), playerStartX[i].getText(), 
        playerStartY[i].getText()); 

     } catch (Exception e) { 
      System.out.println("Failed to create processes for players"); 
      e.printStackTrace(); 
     } 
    } 
} 

이 내가 쓴 기능이는/스레드 (들) 시작되는 클래스 (들)을 실행합니다. 다음 클래스는 실행됩니다

내 두 번째 시도에서
public class StartProcesses{ 

public static void main(String[] args) { 

     Thread t = null; 
     t = new Thread(new HexagonRunner("127.0.0.1",6000,"UnitedTestors",-30,-15)); 
     t.start(); 
      JOptionPane.showMessageDialog(null, "should've started"); 
} 
} 

는 StartProcesses 클래스에 제공되는 매개 변수는 다음과 같이 IP-Adresses, Portnumbers, Playerpositons 물건과 같은 몇 가지 정보를 포함하고 있습니다. 어쨌든 "하드"정보로 클래스를 실행하려고했는데 첫 번째 코드 파트에서와 같이 작동하는지 확인해야합니다.

서버 연결은 두 시도에서 모두 올바르게 설정되지만 첫 번째 시도에서는 스레드가 계속 작동합니다. 두 번째 시도에서 연결이 설정된 후에 스레드가 죽은 것처럼 보입니다. 프로세스는 아직 서버에 연결되어 있으므로 아직 살아 있습니다.

이것은 약간의 코드입니다.하지만 말해야 할 것은 수동으로 실행하면 스레드가 올바르게 작동하지만 ProcessBuilders를 사용하여 클래스를 자동으로 시작하려고하면 올바르게 작동하지 않는다는 것입니다.

나는 정말로 정말로 너희들이 내가 무엇을 말하려고하는지 이해할 수 있기를 바란다. 바라건대 누군가 나를 위해 일하는 해결책을 가지고 있기를 바랍니다.

건배.

편집 : HexagonRunner에 대한 코드를 추가

public class HexagonRunner extends GeneralAgent { 

// Bunch of Methods 
// Important Method: 

    @Override 
protected void simulationCycle() { 

    turnAgent(40); 


} 
} 

simulationCycle() 메소드는, 또 다시 통과 될 것입니다 방법입니다. 클래스 HexagonRunner이 클래스 GeneralAgent에서 상속되기 때문에 , 내가 여기뿐만 아니라이 클래스의 관련 물건을 게시거야 :

public class GeneralAgent implements Runnable, UdpListener{ 

// Attributes, getters, setters, methods.. 

@Override 
public final void run() { 
    // giving the worker threads the signal to start 
    mServerConnection.start(); 
    mParser.start(); 

    // waiting for the first information to be parsed, so that the 
    // simulation loop can run 
    try{ 
     System.out.println("GeneralAgent-Run: waiting for latch"); 
     mLogger.info("Run method: waiting for CountDownLatch"); 
     mFirstDone.await(); 
    } 
    catch(InterruptedException e){ 
     System.out.println("GeneralAgent-Run: InterruptedException"); 
     mLogger.info("Run method error: " + e.getMessage()); 
    } 
    mLogger.info("Run method: CountDownLatch now 0, continue"); 
    // setting the initial position 
    moveToPostion(mXStartCoord, mYStartCoord); 

    // the simulation loop 

    while (true){ 
     simulationCycle(); 

     // Shutdown if the game is over 
     if (mGameworld.getTime() >= 6000){ // later 6000+ 
      System.out.println("Yeah, 50 runs completed -> Shutdown"); 
      mLogger.info("General Agent - Time > 50, programm should terminate"); 
      shutdown(); 
      break; 
     } 
     // waiting for the threads to signal that they are 
     // ready (e.g. have new server information) 
     // for another round of the simulation loop 
     mPhaser.arriveAndAwaitAdvance(); 
    } 
} 

나는 일이 지금 명확하게 얻을 수 있기를 바랍니다. 나는 아직도 내 코드가 실패한 곳을 모른다.

+0

"제대로 작동하지 않습니다"는 적절한 문제 설명이 아닙니다. 어떤 일이 일어 났는지 설명하십시오. 의도하지 않은 일이 발생하거나 그 일이 일어나지 않는 경우를 설명하십시오. 오류 메시지 또는 예외가있는 경우 질문에 포함하십시오. – Holger

+0

오,이 부분을 깜빡입니다. 그것은 제대로 작동하지 않습니다. 스레드의 메커니즘이 한 번만 실행되는 것처럼 보입니다. 내 HexagonRunner Thread에 JOptionPane 호출을 구현했습니다. 생성 된 프로세스에서 스레드를 시작하면 JOptionPane이 한 번만 열립니다. 스레드로 수동으로 클래스를 실행하면 JOptionPane이 requlary로 표시됩니다. –

+0

글쎄, 그 'JOptionPane'을 다루는 실제 코드를 보지 않고서는 그 문제를 해결하기가 어렵습니다. 그러나 일반적으로 Swing 기능은 백그라운드 스레드에 의해 액세스되지 않아야합니다. [ "Swing의 스레딩 정책"(http://docs.oracle.com/javase/7/docs/api/javax/swing/package-summary.html#threading)을 참조하십시오. 당신이 그것을 따르지 않는다면 결과는 예측할 수 없을 것입니다. – Holger

답변

0

Executors를 사용하면 훨씬 간단하게 만들 수 있습니다. 그것은 Java 1.5에서 소개 된 comcurrent 패키지의 일부입니다.훨씬 간단하게입니다

// create a pool with 10 threads 
ExecutorService executorService = Executors.newFixedThreadPool(10); 
//loop as long as you need to detach your threads 
for (int i = 0; i < 4; i++) { 
    // this actually contains the thread bit, will be executed in parallel 
    executorService.execute(new Runnable() { 
     public void run() { 
      // this is where your code is 
      new HexagonRunner("127.0.0.1",6000,"UnitedTestors",-30,-15) 
     } 
    }); 
} 
// clean up when you're done to prevent leaks 
executorService.shutdown(); 

을하고 많이 느린 ProcessBuilder를 통해 서로 다른 JVM의를 생성 할 필요가 없습니다 : 기본적으로 다음과 같이 작동합니다.

+0

이것은 꽤 좋아 보이지만 내 주요 목표 중 하나를 포함하지 않습니다. HexagonRunners는 별도의 프로세스에서 실행되어야합니다. 이 HexagonRunners는 실제로 일종의 인공 지능을 가진 축구 선수입니다. 서버 규칙 중 하나는 각 플레이어가 진행중인 작업을해야한다는 것입니다. 이 이유는 플레이어가 서버 기능과 다른 방식으로 통신하지 않을 수 있기 때문입니다. –

+0

글쎄, 괜찮 았어, 당신은 여전히 ​​Runnable() 메서드의 ProcessBuilder 물건을 당신과 함께 포함시킬 수 있습니다. 실행 프로그램을 사용하면 실제로 여러 스레드를 생성하는 문제가 명령 행 호출을 실행하는 것과 분리됩니다. –

+0

나는 너를 이해하지 못하거나 너는 나를 이해하지 못한다. 나는 그것을 조금씩 설명하려고 노력한다. 각 HexagonRunner는 다른 사람과 분리되어 시작되어야합니다. 즉, 모든 HexagonRunner는 자체 프로세스 (JVM)를 가지고 있어야합니다. 한 클래스에서이 HexagonRunners를 간단히 시작할 수는 없습니다. –