2016-08-02 24 views
1

Ich habe einen neuen Thread namens ThreadA erstellt und diesen im Hauptthread gestartet.Die Steuerung kehrt nach der Benachrichtigung nicht zum wartenden Thread zurück

Ich wartete auf einige Operationen in ThreadA abgeschlossen werden.

Nach einigen Operationen habe ich Benachrichtigung gesendet notify.

Aber der Code unter den wait im Hauptthread wird nicht aufgerufen, wartet sie auf den gesamten Code der ThreadA abzuschließen.

Ist es die Art der Threading oder einfach Thread Zugang zum Laufproblem zu bekommen?

Job job = new MyJob(); 
job.schedule(); 
synchronized(job) { 
    job.wait(); 
    sysout("After notify"); 
} 

Hier job ist org.eclipse.core.runtime.jobs

Inside Job ausführen Methode:

run { 
    synchronized(this) { 
     step 1(); 
     notify(); 
     step 2(); 
    } 
} 

Hier Schritt 2 ist groß Code.

+2

Bitte zeigen Sie Ihren Code (wie genau Sie rufen "warten" und "benachrichtigen"). – yole

+0

Job job = neu MyJob(); job.schedule(); synchronisiert (job) {job.wait(); sysout ("Nach Benachrichtigung")} Hier ist der Job org.eclipse.core.runtime.jobs. – user3302323

+0

Inside Job run-Methode: run {synchronized (this) {step 1(); benachrichtigen(); Schritt 2();}} Hier ist Schritt 2 großer Code. – user3302323

Antwort

1

Der Benachrichtigungs-Thread sendet die Benachrichtigung nicht, bis die Sperre aufgehoben wird. Sie müssen die Sperre aufheben, bevor die Benachrichtigung erfolgen kann, und Ihr Code tut dies nicht.

Dann hat der Thread, der die Benachrichtigung erhält, natürlich nicht die Sperre. Sie muss die Sperre erwerben, bevor sie aktiv werden kann. Wenn der Thread wartet, muss er die Sperre anfordern, bevor er die Wait-Methode beenden kann. Es gibt keine Präferenz für den gemeldeten Thread und keinen Grund zu denken, dass er als nächstes handeln muss.

Dies ist ein Teil davon, warum es ratsam ist, immer in einer Schleife zu warten, was Sie nicht tun. Der Weckfaden sollte überprüfen, ob der Zustand, in dem er geweckt wurde, immer noch wahr ist, sobald er das Schloss erhalten hat.

Ihre Job-Run-Methode enthält die Sperre vom Aufruf von Schritt1 bis zum Aufruf von Schritt2. Damit der benachrichtigte Thread irgendetwas über die Benachrichtigung tun kann, muss er nicht länger warten, was dazu führt, dass die Sperre erneut angefordert wird, bevor sie die Wait-Methode beenden kann (weil sie ihren eigenen synchronisierten Block eingeben muss). Das bedeutet, dass es keinen Sinn macht, die Benachrichtigung zu senden, bevor der Benachrichtigungs-Thread die Sperre aufgibt, da der wartende Thread sowieso nichts dagegen tun kann.

+0

Erwirbt Synchronized (Job) die Sperre für dieses Objekt? – user3302323

+0

@ user3302323 Das Schlüsselwort 'synchronize' markiert einen Block, der nur von einem einzelnen Thread gleichzeitig eingegeben werden kann. Wenn sich ein anderer Thread derzeit in einem synchronisierten Block für dasselbe Objekt befindet, wird die Ausführung angehalten, bis der andere Thread seinen synchronisierten Block –

+0

verlassen hat. Können Sie bitte im Detail erklären, wie Sie Sperren für Objekte freigeben und erfassen können? – user3302323