2016-05-04 9 views
1

I haben eine innere Klasse, die GewindeGriff Java-Ausnahme in Thread.run

private class TestStart extends Thread { 
    public void run() { 
     try { 
      startServer(); 
     } 
     catch (Exception e) { 
      /// How to handle it? 
     } 
    } 
} 

der Anrufer im Hauptthread erstreckt:

public void start() throws Exception { 
    Thread st = new TestStart(); 
    st.start(); 
} 

Methode start() throws Exception durch seine API, so Ich muss try-catch verwenden, da Thread.run() in der Methodendefinition keine Ausnahme "wirft". Ich muss die gefangene Ausnahme in den Haupt-Thread aufblasen, um damit umzugehen. Gibt es einen einfachen Weg, es zu tun? Danke

+1

Wie starten Sie diese Themen? Wenn Sie einen 'ExecutorService' verwenden würden, wäre es möglich, ein 'Runnable' zu senden und ein' Future 'zu erhalten; Das Aufrufen von 'get()' auf diesem 'Future' würde eine' ExecutionException' ergeben, wenn eine Ausnahme in dem 'Runnable' geworfen würde. –

+0

Siehe [http://stackoverflow.com/questions/1369204/how-to-throw-a-checked-exception-from-a-java-thread](http://stackoverflow.com/questions/1369204/how- two-throw-a-checked-exception-from-a-java-thread) –

Antwort

3

Wenn Sie ein ExecutorService anstelle rohen Faden zu verwenden, können Sie nicht abgefangene Ausnahmen gemeldet werden:

class MyCallable implements Callable<Void> { 
    @Override public Void call() throws Exception { 
    // Do something - you don't need to catch Exception as Callable throws it. 
    // ... 

    return null; // A return is necessary from a Callable. 
    } 
} 

Einen Testamentsvollstrecker Service irgendwo, zB:

ExecutorService executor = Executors.newFixedThreadPool(1); 

Dann im Code Wo starten Sie den Thread:

Future<?> future = executor.submit(new MyCallable()); 

try { 
    future.get(); // Blocks until the Callable completes. 
} catch (ExecutionException e) { 
    // You reach here if an exception is thrown in the Callable - 
    // The exception is accessible via e.getCause(). 
} 
+0

ExecutorService funktioniert gut. Vielen Dank – CMZS

0

Legen Sie einen neuen Ausnahmebehandler auf Ihrem Thread fest.

st.setDefaultUncaughtExceptionHandler(new Thread. 
      UncaughtExceptionHandler() { 
       public void uncaughtException(Thread t, Throwable e) { 
       System.out.println(t + " throws exception: " + e); 
      } 
    }); 

und legen Sie diesen Code vor Ihrem Start();

0

Es gibt ein paar mögliche Lösungen. Zum Beispiel:

  1. Verwendung setUncaughtExceptionHandler()/setDefaultUncaughtExceptionHandler() und ändern Sie Ihre try/catch

    try { 
        startServer(); 
    } 
    catch (RuntimeException e) { 
        throw e; 
    } 
    catch (Exception e) { 
        throw new RuntimeException(e); 
    } 
    
  2. Oder nutzen Sie Ihre individuelle Zuhörer

    private class TestStart extends Thread { 
        private final ServerStateListener lnr; 
    
        TestStart(ServerStateListener lnr) { 
         this.lnr = lnr; 
        } 
    
        public void run() { 
         try { 
          startServer(); 
          lnr.onServerStarted(); 
         } 
         catch (Exception e) { 
          lnr.onServerStoppedByError(e); 
         } 
        } 
    } 
    
  3. Oder einfach speichern Ausnahme und lesen Sie es nach .join

    private class TestStart extends Thread { 
        private Exception error; // if you start and join and read this property within one thread, you don't need to use volatile, otherwise do it for safe publication 
    
        public void run() { 
         try { 
          startServer(); 
         } 
         catch (Exception e) { 
          error = e; 
         } 
        } 
    
        public Exception getError() { 
         return error; 
        } 
    } 
    
  4. Oder verwenden Sie ExecutorService/Callable anstelle von Ihrem eigenen Thread wie Andy vorgeschlagen.