Also habe ich ein Problem mit Semaphor. Einen Code schreiben, wo 4 Zimmer und einige Besucher sind. Jedes Zimmer hat eine bestimmte Grenze für die Anzahl der Besucher, die sie halten können. Wenn Sie also einen vollen Raum betreten, wird eine Wartezeit ausgelöst (). Die Besucher dürfen ein Zimmer nicht verlassen, bevor sie ein anderes betreten können, also sind sie immer in einem Raum.
%Vor% Deadlock erscheint, wenn zwei Personen versuchen, die Räume des anderen zu betreten.
Auch aus irgendeinem Grund kommt die placesLeft
-Zahl nicht richtig raus.
Was soll ich tun?
BEARBEITEN:
Sie waren mit etwas anderem beschäftigt und haben die Frage neu belebt. Das Problem tritt nicht auf, weil die Räume voll werden, die Sperre eintritt, wenn Person1 von Raum1 in Raum2 eintreten will und gleichzeitig Person2 von Raum2 in Raum1 eintreten möchte. Wie verstehe ich vielleicht etwas mit Synchronisieren? Sie bleiben vor der Veröffentlichung stecken, daher wird die Veröffentlichung nicht aufgerufen. Wie ich verstehe, ein Zimmer accuire und Release kann nicht gleichzeitig aufgerufen werden. Also kann die Semaphorfreigabe von room1 nicht cuz genannt werden, wenn der Accuire gleichzeitig für room2 aufgerufen wird? Ich bin Neuling Coder und Synchronisierung ist noch nicht so klar. Entfernen von einer der anderen synchronisiert scheint nicht zu funktionieren (ist prolly auch falsch).
Anstatt Ihre eigenen zu implementieren, sollten Sie java verwenden. util.concurrent.Semaphore , das in die Java Standard Library eingebaut ist?
Das java.util.concurrent
-Paket hat ein tolles Tutorial , das Semaphore und die vielen anderen nützlichen Synchronisationsmechanismen abdeckt was es bietet.
Deadlock tritt auf, wenn im Abhängigkeitsgraphen ein Zyklus vorliegt. Wenn zwei Menschen versuchen, die Räume des anderen zu betreten, ist dies offensichtlich ein Zyklus, und Stillstand ist eine natürliche Folge.
Sie möchten jedoch Zyklen auf andere Weise behandeln: Wenn ein Zyklus auftritt, bewegen sich alle Personen entlang des Zyklus (es können mehr als zwei Personen Zimmer tauschen).
Sie sollten also zuerst feststellen, ob sich ein Zyklus gebildet hat, und dann die Standorte der Besucher ändern.
Fügen Sie eine Liste der aktuellen Besucher zu Room
hinzu, so dass Sie in acquire
einchecken können, wenn der ankommende Besucher aus einem Raum kommt, auf den einer der Bewohner dieses Raums wartet. Sie müssen außerdem den Raum hinzufügen, auf den ein Besucher wartet, um ihn in Visitor
einzutragen.
Ich bin ein wenig unsicher in Bezug auf die Logik, um zu überprüfen, ob ein Besucher darauf wartet, in denselben Raum zu gelangen, den der aktuelle Besucher verlässt. Ich kann nicht sagen, welches Zimmer room
den Code darstellt.
Um Ihre Frage zu beantworten: "Was soll ich tun?" Wenn Sie einen Deadlock entdecken, bewegen Sie einen der festgefahrenen Besucher in einen Raum mit Platz. Dann bewege ihn zu dem Raum, den er wirklich will. Dies erlaubt grundsätzlich einen Tausch, ohne gegen eine der folgenden Regeln zu verstoßen.
Denken Sie daran, es gibt ungefähr eine Million Semaphor-Sperrstrategien da draußen ...
Versuchen Sie Folgendes:
%Vor% Der alte Code wurde auf den einzelnen Semaphore-Instanzen synchronisiert. Es ist sehr schwierig, Deadlocks zu verhindern, weil die Methode acquire()
einer Instanz release()
einer anderen Instanz aufruft. Der Aufruf von release()
blockiert dann, wenn ein anderer Thread gerade die Methode acquire()
für diese andere Instanz ausführt. Wenn dieser zweite Thread schließlich release()
für die erste Instanz aufruft, haben Sie einen Deadlock.
Ich habe die Synchronisierung der einzelnen Semaphore-Instanzen durch Synchronisation auf ein einzelnes Objekt namens LOCK
ersetzt. Der Thread, der acquire()
ausführt, hat den Monitor von LOCK
gesperrt. Dieser Thread wird daher nicht blockiert, wenn er die Methode release()
aufruft. Die Methode release()
wird daher immer beendet. Dies löst den Deadlock.
Deadlocks werden normalerweise durch ein hierarchisches Semaphor-System aufgelöst. Typische Dead-Sperre sieht wie
ausProzess A
%Vor%Prozess B
%Vor% Nur für alle Prozesse, die A vor B auswählen. Dies kann erreicht werden, indem Sie Ihre getSemaphore
-Funktion schreiben, um die Hierarchie mit Behauptungen durchzusetzen.
Für Ihren speziellen Fall löst das das Problem nicht sehr offensichtlich, aber Sie können von dieser Idee ableiten.
Erstellen Sie eine Migrationswarteschlange. Wenn ein Benutzer die Räume wechseln möchte, könnte die Funktion wie folgt aussehen:
%Vor%Das "3200" ist ein Semaphor-Timeout. Wenn ein Prozess nach dem Speichern des Semaphors unterbrochen wird, wird das System weiterhin blockiert. Dies gibt eine 1-Stunden-Zeitüberschreitung. Sie können es basierend auf Ihrer Systemstabilität auf einen logischen Wert von 1 Minute, 5 Sekunden setzen. Dann haben Sie einen Warteschlangenprozessor, der nur eine Übertragung zu einem Zeitpunkt mit einem nicht blockierenden Semaphor erlaubt
%Vor%Der Schlaf sorgt dafür, dass der Warteschlangenprozess den Prozessor überfordert. Stellen Sie es auf eine entsprechende Überprüfung ein. Sie können Interrupts auch so einrichten, dass Warteschlangenelemente nur dann gezogen werden, wenn in einem Raum ein Leerzeichen geöffnet oder eine Transition hinzugefügt wurde. Auf diese Weise wird, wenn ein Raum voll ist, keine Zeit mit dem Versuch verschwendet, hineinzukommen, aber jeder wird mindestens einen Schuss haben, um sofort hineinzukommen.
Dies erzwingt einen Übergang, um den Warteschlangen-Semaphor zu erhalten, bevor sie einen Raumsemaphor erhalten können. Einrichten einer Deadlock-freien Hierarchie Ein Benutzer wird die Warteschlange niemals verlassen, wenn ein Raum voll ist, aber das System wird nicht blockiert.
Tags und Links java multithreading deadlock semaphore