2015-04-17 7 views
20

Zum Beispiel:Bekommt der Haupt-Thread sofort nach dem Aufruf der start() -Methode eines Threads die Kontrolle?

public class Example1 { 

    public static void main(String[] args) { 
     Loop loop = new Loop(); 
     loop.start(); //printing "Before start" 
     System.out.println("After start"); 
    } 
} 

eine Situation sein kann, dass die loop ‚s run-Methode endet vor der Ausführung der letzten Zeile, den Druck‚Nach dem Start‘?

+0

Kurze Antwort: Der Haupt-Thread bleibt einsatzbereit und wird, wenn mindestens ein freier Kern vorhanden ist, wahrscheinlich ohne Unterbrechung weiterlaufen. Aber du weißt nie. –

+0

Selbst wenn der Haupt-Thread garantiert die Kontrolle übernahm, könnte er später die Kontrolle verlieren. – usr

+0

@ user704023 Wenn eine der folgenden Antworten Ihnen mehr Einblick geben konnte oder Ihr Problem gelöst wurde, dann überlegen Sie, ob Sie eine als akzeptierte Antwort markieren, damit nützliche Informationen hervorgehoben werden. – MSB

Antwort

41

Sobald Sie Multithreading starten, sollten Sie alle Annahmen Sie haben über die Reihenfolge, in der Threads ausgeführt werden.

Wenn es wichtig ist, können Sie Synchronisierungsvorgänge verwenden, aber ohne sie sind alle Wetten deaktiviert.

11

Ja, Sie haben keine Kontrolle darüber, wie die Threads von der JVM ausgeführt/geplant werden.

Wenn Sie eine Art der Reihenfolge einführen möchten (führen Sie die zwei Threads nacheinander aus), wäre die einfachste Möglichkeit, eines der Lock Objekte zu verwenden, die Java bereitstellt.

+0

Das oder zwei Runnables zu einem single-threaded Executor übergeben. –

+0

Ja! Einen Executor zu verwenden, wäre vom Design her viel besser. –

11

Sie fragen grundsätzlich nach Thread-Sicherheit in Java (zumindest verstehe ich das aus der Frage). Als eine der früheren Antworten bereits angegeben, ist es eine gute Idee, alle Annahmen, die Sie über Ausführungsreihenfolge haben, wenn mehrere Threads ausgeführt werden.

Jedoch (!) Ist es möglich, Designprinzipien und kritisches Denken zu verwenden, um Ihre Anwendung so zu modellieren, dass keine unerwünschten Nebenwirkungen durch Multithreading auftreten können.

Für den Anfang Sie diesen Artikel auf Designing Object Initilization Der Kern des Artikels lesen ist, dass Sie Ihre Klassen als finite state machines denken. Wenn Sie nicht wissen, was sie sind: finite state machines in einer Reihe von Staaten (daher der Name).

Die Idee ist, dass, wenn Sie in Zustand sind (A) Sie das Verhalten festlegen, dass dieser spezifische Zustand durchführen kann: (A) -> (B), (A) -> (C) ich von Staat gehen kann (A)(B) und (C) zu erklären, aber nicht zu erklären, (D) Dies (es sollte vorhanden sein) Mindset ist wichtig zu verstehen, was Ihre Anwendung CAN in jeder gegebenen Situation tun kann.(Fine State Machines Wikipedia)

Sobald Sie dies verstehen, können Sie auf bewegen Der Fix:

Es gibt drei Möglichkeiten, ein Objekt Thread-sicher zu machen:

  • synchronisieren kritische Abschnitte
  • Make it unveränderlich
  • Verwenden Sie einen Thread-sicheren Wrapper
in Java Dokumentation

Jeder Ansatz hat seine eigenen Vorteile/Nachteile, die hier erläutert werden:

Hoffentlich wird Ihnen ein besseres Verständnis gegeben von Die Komplikationen, denen Sie beim Erstellen von Multithread-Anwendungen begegnen können.

+0

Dies ist eine gute Antwort, aber es hat ein paar ärgerliche kleine Fehler, wie ungerade Großschreibung und ein etwas herablassender Ton ("wenn Sie nicht belästigt werden, es zu lesen" ist ein prominentes Beispiel) –

+3

Der Ton war nicht gemeint in ein bevormundender Weg, aber es wurde ordnungsgemäß zur Kenntnis genommen, ich schrieb die Antwort um. Ich hoffe, dass die Informationen nun besser dargestellt werden. – MSB

6

Wenn ich einen Join im Thread und einige weitere print-Anweisungen hinzufüge, können einige der Eigenschaften erklärt werden.

public class Example1 { 

    public static void main(String[] args) { 
     Loop loop = new Loop(); 
     System.out.println("Before start"); 
     loop.start(); //printing "Before start" 
     System.out.println("After start"); 
     loop.join(); 
     System.out.println("After join"); 
    } 
} 

"Vor dem Start" wird immer gedruckt werden, bevor loop.run() ausgeführt wird.

"After Join" wird immer gedruckt werden, nachdem loop.run() fertig ist.

"After start" hat keine Garantie auf, wenn es in Bezug auf die loop.run() gedruckt wird; Es kann vorher sein, kann es sein nach, es kann während der Ausführung mit print-Anweisungen in loop.run() verschachtelt werden.

Wenn Sie Garantien benötigen, dann benötigen Sie andere Synchronisierungshilfsprogramme wie Sperren und Semaphoren.

Verwandte Themen