Exceptions im Thread

Hi, ich möchte gern aus meine main Funktion eine Thread starten und alle Exception die in diesem Thread geworfen werden in der main Funktion behandeln. Leider stelle ich mich dafür ein bisschen blöd an. Hier mal ein auszug aus dem Programm.

Code:
public class testKlasse {
     
    public static void main(String args[]) {
        try {
             Thread t = testThread();
              t.start();
        }
        catch(Exception e) {
            System.out.println("Exception im Thread: "+e);
        }
    }

Code:
public class testThread extends Thread{ 
    public testThread() {
    }

    public void run()   {
         //mache ihr irgendwas
   }
}

Ich dachte mir, das es reichen wird dies wie folgt zu machen.
Code:
public void run() throws Exception {
    //mache irgendwas
}

Leider bekomme ich dann folgende Fehlermeldung vom Compiler:
testThread.java:95: run() in testThread cannot implement run() in java.lang.Runnable; overridden method does not throw java.lang.Exception

Weiß einer von euch was ich da falsch mache und wie es richtig geht? Es muss halt leider sein, dass alle Exception aus dem Thread hochgereicht werden.
 
Hallo!

So wie du das machen möchtest geht das natürlich nicht...
sobald die start() Methode eines Thread aufgerufen wird wird der native Betriebsystem Thread erzeugt und gestartet. Die start() Methode kehrt dabei sofort zurück.

Wenn du generisch auf (unbehandelte) Exceptions in Threads reagieren möchtest könntest du's mal mit einem UncaughtExceptionHandler versuchen:
Java:
/**
 * 
 */
package de.tutorials;

import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.TimeUnit;

/**
 * @author Tom
 * 
 */
public class ThreadExceptionCatcher {

    /**
     * @param args
     */
    public static void main(String[] args) {

        final Thread.UncaughtExceptionHandler uncaughtExceptionHandler = new UncaughtExceptionHandler() {
            public void uncaughtException(Thread t, Throwable e) {
                System.out.println("Exception " + e.getMessage()
                        + " occured in " + t.getName());
                e.printStackTrace();
            }
        };

        Runnable runnable = new Runnable() {
            public void run() {
                Thread.currentThread().setUncaughtExceptionHandler(
                        uncaughtExceptionHandler);

                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + ": "
                            + i);
                    try {
                        TimeUnit.MILLISECONDS.sleep(500L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                throw new IllegalStateException("Oh oh");
            }
        };

        new Thread(runnable).start();
        new Thread(runnable).start();
        new Thread(runnable).start();

        //btw. unter Java 5 sollte man new Thread(runnable).start(); nicht mehr verwenden
        //stattdessen würde sich beispielsweise:
        // Executors.newSingleThreadExecutor().execute(runnable);
        // anbieten.

    }
}

Gruß Tom
 
Dies wäre ein Ansatz, aber hiermit kann ich natürlich nur nicht behandelte Exceptions in diesen Thread abfangen. Das Problem ist das z.B. bei Socket Verbindungen immer verlangt wird, dass diese abgefangen werden. Dies kann man ja meiner Meinung nach auch nicht umgehen.
Ziel von mir sollte es eigendlich sein, grundsätzlich alle Exceptions nicht in diesem Thread abzufangen, sondern die Exceptions an den Main Thread hochzureichen.
 
Hallo!

Sowas wäre auch möglich:
Code:
/**
 * 
 */
package de.tutorials;

import java.util.concurrent.TimeUnit;

/**
 * @author Tom
 * 
 */
public class ThreadExceptionCatcher {

    static GenericExceptionHandler genericExceptionHandler = new GenericExceptionHandler();

    /**
     * @param args
     */
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println(Thread.currentThread().getName() + ": "
                            + i);
                    try {
                        TimeUnit.MILLISECONDS.sleep(500L);
                        if (i % 2 == 0) {
                            try {
                                throw new Exception(i + " is even");
                            } catch (Exception e) {
                                genericExceptionHandler.handleException(e);
                            }
                        }
                    } catch (InterruptedException e) {
                        genericExceptionHandler.handleException(e);
                    }
                }
            }
        };

        new Thread(runnable).start();
        new Thread(runnable).start();
        new Thread(runnable).start();
    }

    static class GenericExceptionHandler {
        public void handleException(Exception e) {
            System.out.printf("[%s]", System.currentTimeMillis());
            e.printStackTrace();
        }
    }
}

Weshalb willst du alle Exceptions eigentlich innerhalb des Main-Threads behandeln?
CheckedExceptions musst du innerhalb eines Threads auf jeden Fall behandeln, UnCheckedExceptions (RuntimeExceptions) kannst du an jeder beliebigen Stelle fliegen lassen ohne sie behandeln zu müssen. (Man kann CheckedExceptions auch in UncheckExceptions Wrappen). Das was du da im Grunde machen möchtest ist eine generische Ausnahmebehandlung, was meiner Meinung zu gewissen Teilen recht problematisch ist, denn oftmals sind (Fachliche) Ausnahmen sehr spezifisch, so dass man eigentlich nicht auf eine generische Art und Weise darauf reagieren kann. Was man IMHO sehr generisch lösen kann sind Geschichten wie Exception loggen, Transaktionen zurückrollen, Resource Clean up etc...

Gruß Tom
 
Danke schonmal für die Antwort Tom.
So könnte am diese auch lösen. Ich habe aber noch eine andere Variante gefunden und zwar die Rückgabe aus Threads mittels Callable. Hier könnte man dann eine Try-finally Block machen und im finally Block die Rückgabe. (Wäre zwar nicht ganz so das was ich wollte, aber damit könnte ich leben)

Aber dann nochmal kurz ne Frage zum finally Block: Der finally Block wird immer ausgeführt, auch wenn zuvor eine Exceptions geworfen wurden. Was passiert aber, wenn im finally Block eine Exception geworfen wird? Wird der Teil hinter der Exception trotzdem noch ausgeführt, oder wird dann an dieser Stelle der finally Block geschlossen? Ich könnte mir hier also z.B. vorstellen die Socket Verbindung zu schließen und die Streams etc. und somit sicher gehen, das alles korrekt geschlossen wurde.
 

Neue Beiträge

Zurück