Anzeige:
Ergebnis 1 bis 3 von 3

Thema: Initial Thread und invokeLater

  1. #1
    Registrierter Benutzer Avatar von BlueJay
    Registriert seit
    27.08.2004
    Beiträge
    825

    Initial Thread und invokeLater

    Hallo Leute,

    ich habe da mal eine Verständnisfrage zur Main-Klasse und invokeLater:

    Es ist ja so, dass für Main ein Initial-Thread gebildet wird. Wie lange lebt der im unteren Fall?


    Code:
    public class Main
    { final static String titel="Java-Experimente";
      static JFrame my_frame;
    
      public static void Main(String[] args)
      {  
        javax.swing.SwingUtilities.invokeLater(new Runnable()
        { 
    	  public void run()
             {  
                my_frame=new JFrame(titel);
                my_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                my_frame.setMinimumSize(new Dimension(480,360));
                u.s.w.
    		..
    		..
    		my_frame.pack();
    		// ab da nur noch eventgetrieben bzw. mit eigenen Threads
    	  }
        }
    	// hier später noch ein bisschen zum Testen reingehängt
      }
      
    }
    Kickt der einfach nur das Runnable an und ist dann weg (invokeLater)? Oder lebt der bis zum Programmende?
    Lebt er bis zum Programmende, wenn man statt invokeLater invokeAndWait nimmt?

    Wie wirkt invokeLater tatsächlich? Der hier gefundenen Sachverhalt im 1.Beispiel konnte von mir nicht bestätigt werden:
    http://www.dpunkt.de/java/Programmie...ierung/67.html

    der Initial-Thread und der EventDispatchThread mit invokeLater arbeiteten fröhlich durcheinander.

    Sorry, ich habe dazu so viel Artikel gelesen, die sich teilweise widersprachen sowie nicht zu meinen Testergebnissen passten, dass ich mal nachfragen muss.

    Gruß,Ulrike
    Eigentlich ganz einfach, wenn man's weiss!

  2. #2
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Ist schon ein bischen her seit ich das letzte Mal Java benutzt habe, aber ich denke der Haupthread existiert so lange wie der Java Prozess läuft.

    In Bezug auf die beiden Invoke Varianten würde ich davon ausgehen, dass beide das selbe "Invoke Event" benutzen, um den Aufruf an aktuell letzter Stelle in die Eventqueue einzuhängen.

    D.h. der Eventthread wird das Invoke genau so behandlen als wäre eine Benutzerinteraktion zu diesem Zeitpunkt eingegangen, d.h. das Runnable.run() wird aufgerufen, sobald der Eventhread an diesem Punkt seiner Verarbeitungswarteschlange angelangt wird.

    Im Falle der "AndWait" Variante wird das Abarbeiten der Events einfach direkt angetrieben, während im der Variante ohne Wait einfach der Haupteventschleife die Kontrolle überlassen wird.

    In stark vereinfachter Form sieht das in etwa so aus

    Code:
    // run des Eventthread
    void run() {
        while (true) {
            Event event = getEventFromQueue();
            processOneEvent(event);
        }
    }
    
    void processOneEvent(Event event) {
        if ( event instanceOf EventA ) {
           processEventA( (EventA) event );
        } else if ( event instanceOf EventB ) {
           processEventB( (EventB) event );
        } else if ( event instanceOf InvokeEvent ) {
           processInvoke (Invoke) event );
        }
    }
    
    void processInvoke(InvokeEvent event) {
        Runnable runnable = event.getRunnable();
        runnable.run();
    }
    
    void processEventA(EventA event) {
        invokeLater(new Runnable() { ... } )
    }
    
    void processEventB(EventB event) {
        invokeLaterAndWair(new Runnable() { ... } )
    }
    
    void invokeLater(Runnable runnable) {
        InvokeEvent invokeEvent = new InvokeEvent( runnable );
        putEventIntoQueue( invokeEvent );
    }
    
    void invokeLaterAndWait(Runnable runnable) {
        InvokeEvent invokeEvent = new InvokeEvent( runnable );
        putEventIntoQueue( invokeEvent );
        // so weit gleich wie invokeLater
    
        // jetzt lokal Eventverarbeitung durchführen bis unser Event dran war
        while (true) {
            Event event = getEventFromQueue();
            processOneEvent(event);
            if (event == invokeEvent) break;
        }    
    }
    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  3. #3
    Registrierter Benutzer Avatar von BlueJay
    Registriert seit
    27.08.2004
    Beiträge
    825
    Soweit mir bekannt ist, sind Initial Thread und Event Dispatcher Thread zwei verschiedene Threads. Das deckt sich mit der Beobachtung, dass Anweisungen wom Initial-Thread und EDT fröhlich durcheinanderlaufen, wenn die Arbeitslisten entsprechend groß sind.

    Mit
    Code:
     public static void checkthread()
     {
        if (javax.swing.SwingUtilities.isEventDispatchThread()) System.out.println("löppt im EDT");
       else System.out.println("löppt nicht im EDT"); 
    }
    lässt sich so was ja schnell herausfinden.

    Das viel propagierte
    invokeLater
    startet den Thread nämlich nicht, wenn der Initial Thread, wie meistens beschrieben, abgelaufen ist, sondern irgendwann, wenn es dazwischenfunken kann. Ausgerechnet bei Sun/Oracle findet man teilweise diese irreführenden Aussagen! Und dann wird nicht erklärt, dass das höchstens so ist, wennd der Initial Thread nix weiter als den EDT anzustoßen hat. Damit ist das Ganze ein Timing-Problem, was meistens gutgeht, aber nur meistens! (ich bin hier mal pingelig!)

    Nun ist es ja so, dass man Methoden schreiben kann, die aus einem Thread irgendeinen Thread ankicken und dann normal weiterlaufen und sich beenden, während der angekickte Thread noch lebt.

    Meine Frage: macht das der Initial Thread auch? Verdrückt er sich, wenn er abgearbeitet ist? Oder behält er die Kontrolle, bis sich hier der später invokte Thread verabschiedet hat? (kriegt eine "Extrawurst" gebraten)

    Für die Praxis heisst das natürlich, dass bei mir der Initial Thread bis auf das Ankicken des EDT nackt bleibt.

    Gruß,
    Ulrike


    Habe inzwischen via Suche nach VM die Lösung bekommen: da hat sich wohl zwischendurch die Architektur geändert. Derzeit ist es so, dass der Initial Thread so lange bestehen bleibt, wie Nicht-Dämon-Threads laufen, und verabschiedet sich erst dann. Er beendet sich sofort, wenn er von einem der Threads ein Exit abbekommt.

    Eventuell gestartete Dämon-Threads laufen nach Verabschieden des Initial Threads weiter. Da der EDT meist nicht als Dämon-Thread gestartet wird, dürfte der Initial Thread wohl die ganze Laufzeit leben.


    d.h., der von anda_skoa vermutete Sachverhalt ist (derzeit?) tatsächlich so.
    Geändert von BlueJay (18-11-2011 um 11:29 Uhr)
    Eigentlich ganz einfach, wenn man's weiss!

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •