Ich habe 2 Matrizen und ich muss sie multiplizieren und dann die Ergebnisse jeder Zelle drucken. Sobald eine Zelle bereit ist, muss ich sie drucken, aber zum Beispiel muss ich die Zelle [0] [0] vor Zelle [2] [0] drucken, selbst wenn das Ergebnis von [2] [0] zuerst bereit ist . Also muss ich es auf Bestellung ausdrucken. Meine Idee ist es also, den Druckerthread warten zu lassen, bis er multiplyThread
benachrichtigt, dass die richtige Zelle zum Drucken bereit ist, und dann printerThread
die Zelle zu drucken und wieder zu warten und so weiter.
Also habe ich diesen Thread, der die Multiplikation macht:
public void run()
{
int countNumOfActions = 0; // How many multiplications have we done
int maxActions = randomize(); // Maximum number of actions allowed
for (int i = 0; i < size; i++)
{
result[rowNum][colNum] = result[rowNum][colNum] + row[i] * col[i];
countNumOfActions++;
// Reached the number of allowed actions
if (countNumOfActions >= maxActions)
{
countNumOfActions = 0;
maxActions = randomize();
yield();
}
}
isFinished[rowNum][colNum] = true;
notify();
}
Thread, der das Ergebnis jeder Zelle druckt:
public void run()
{
int j = 0; // Columns counter
int i = 0; // Rows counter
System.out.println("The result matrix of the multiplication is:");
while (i < creator.getmThreads().length)
{
synchronized (this)
{
try
{
this.wait();
}
catch (InterruptedException e1)
{
}
}
if (creator.getmThreads()[i][j].getIsFinished()[i][j] == true)
{
if (j < creator.getmThreads()[i].length)
{
System.out.print(creator.getResult()[i][j] + " ");
j++;
}
else
{
System.out.println();
j = 0;
i++;
System.out.print(creator.getResult()[i][j] + " ");
}
}
}
Jetzt wirft es mir diese Ausnahmen:
Exception in thread "Thread-9" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-6" Exception in thread "Thread-4" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-5" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-8" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-7" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-11" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-10" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Exception in thread "Thread-12" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at multiplyThread.run(multiplyThread.java:49)
Zeile 49 in multiplyThread
ist das "notify ()". Ich denke, ich muss das synchronisierte anders verwenden, aber ich bin nicht sicher, wie.
Wenn jemand helfen kann, dass dieser Code funktioniert, werde ich ihn wirklich schätzen.
quelle
while(!JobCompleted);
Option ist im Allgemeinen eine schlechte Idee, da sie Ihre CPU zu 100% bindet und ständig dieselbe Variable überprüft (siehe hier )while(!JobCompleted) Thread.sleep(5);
hat dieses Problem nichtwait
wenn der aktuelle Thread eine Sperre für das Objekt hat, für daswait
aufgerufen wird. Ob Sie einensynchronized
Block oder eine synchronisierte Methode verwenden, liegt ganz bei Ihnen.Bei der Verwendung der Methoden
wait
undnotify
undnotifyAll
in Java müssen folgende Dinge beachtet werden:notifyAll
anstelle von,notify
wenn Sie erwarten, dass mehr als ein Thread auf eine Sperre wartet.wait
undnotify
müssen in einem synchronisierten Kontext aufgerufen werden . Weitere Informationen finden Sie unter dem Link.wait()
Methode immer in einer Schleife auf, denn wenn mehrere Threads auf eine Sperre warten und einer von ihnen die Sperre erhalten und die Bedingung zurückgesetzt hat, müssen die anderen Threads die Bedingung nach dem Aufwachen überprüfen, um festzustellen, ob sie erneut warten müssen oder kann mit der Verarbeitung beginnen.wait()
und dienotify()
Methode. Jedes Objekt hat eine eigene Sperre, sodass das Aufrufenwait()
von Objekt A undnotify()
Objekt B keinen Sinn ergibt.quelle
Müssen Sie das überhaupt einfädeln? Ich frage mich, wie groß Ihre Matrizen sind und ob es von Vorteil ist, wenn ein Thread gedruckt wird, während der andere die Multiplikation durchführt.
Vielleicht lohnt es sich, diese Zeit vor der relativ komplexen Einfädelarbeit zu messen?
Wenn Sie es einfädeln müssen, würde ich 'n' Threads erstellen, um die Multiplikation der Zellen durchzuführen (vielleicht ist 'n' die Anzahl der Kerne, die Ihnen zur Verfügung stehen), und dann den ExecutorService- und Future- Mechanismus verwenden, um mehrere Multiplikationen gleichzeitig zu versenden .
Auf diese Weise können Sie die Arbeit basierend auf der Anzahl der Kerne optimieren und verwenden die übergeordneten Java-Threading-Tools (die das Leben erleichtern sollten). Schreiben Sie die Ergebnisse zurück in eine Empfangsmatrix und drucken Sie diese einfach aus, sobald alle Ihre zukünftigen Aufgaben abgeschlossen sind.
quelle
Angenommen, Sie haben eine Black-Box-Anwendung mit einer Klasse namens
BlackBoxClass
methoddoSomething();
.Außerdem haben Sie einen Beobachter oder Zuhörer benannt
onResponse(String resp)
, derBlackBoxClass
nach unbekannter Zeit angerufen wird .Der Ablauf ist einfach:
Nehmen wir an, wir wissen nicht, was los ist
BlackBoxClass
und wann wir eine Antwort erhalten sollen, aber Sie möchten Ihren Code erst fortsetzen, wenn Sie eine Antwort erhalten oder mit anderen Worten einenonResponse
Anruf erhalten. Hier wird 'Helfer synchronisieren' eingegeben:Jetzt können wir implementieren, was wir wollen:
quelle
Sie können Benachrichtigungen nur für Objekte aufrufen, deren Monitor Ihnen gehört. Also brauchst du so etwas wie
quelle
notify()
muss ebenfalls synchronisiert werdenquelle
Ich werde gleich ein einfaches Beispiel zeigen, wie man es richtig benutzt
wait
undnotify
in Java. Also werde ich zwei Klassen mit dem Namen ThreadA & ThreadB erstellen . ThreadA ruft ThreadB auf.und für Klasse ThreadB:
quelle
Einfache Verwendung, wenn Sie möchten So führen Sie Threads alternativ aus: -
quelle
Wir können notify aufrufen, um die Ausführung wartender Objekte als fortzusetzen
Setzen Sie dies fort, indem Sie notify für ein anderes Objekt derselben Klasse aufrufen
quelle
Speichern Sie für dieses spezielle Problem Ihre verschiedenen Ergebnisse in Variablen. Wenn der letzte Teil Ihres Threads verarbeitet wird, können Sie in einem beliebigen Format drucken. Dies ist besonders nützlich, wenn Sie Ihre Arbeitshistorie in anderen Projekten verwenden möchten.
quelle
Dies scheint eine Situation für das Produzenten-Konsumenten-Muster zu sein. Wenn Sie Java 5 oder höher verwenden, können Sie die Blockierungswarteschlange (java.util.concurrent.BlockingQueue) verwenden und die Thread-Koordinierungsarbeit der zugrunde liegenden Framework- / API-Implementierung überlassen. Siehe das Beispiel aus Java 5: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html oder Java 7 (dasselbe Beispiel): http: // docs. oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
quelle
Sie haben Ihren Codeblock ordnungsgemäß geschützt, wenn Sie die
wait()
Methode mit aufrufensynchronized(this)
.Sie haben jedoch nicht die gleiche Vorsichtsmaßnahme getroffen, wenn Sie die
notify()
Methode aufrufen , ohne einen geschützten Block zu verwenden:synchronized(this)
odersynchronized(someObject)
Wenn Sie auf der Oracle - Dokumentation Seite auf beziehen Objektklasse, die enthält
wait()
,notify()
,notifyAll()
Methoden, können Sie unten vorsorglich in all diesen drei Methoden sehenViele Dinge wurden in den letzten 7 Jahren geändert und wir wollen uns andere Alternativen zu den
synchronized
folgenden SE-Fragen ansehen :Warum ein ReentrantLock verwenden, wenn man synchronisiert (dies) verwenden kann?
Synchronisation gegen Sperre
Vermeiden Sie (dies) in Java synchronisiert?
quelle