Ungewöhnliches Java-Verhalten - warum funktioniert das?

9

Ich habe ein interessantes Verhalten gefunden ... Ich kann mich nicht entscheiden, ob es ein Fehler oder eine Inkompetenz ist, aber ich stehe momentan auf Inkompetenz.

Dieser Code tritt nicht in die Schleife ein, selbst wenn Nachrichten warten:

%Vor%

Dieser Code tritt in die Schleife ein, beachten Sie die Null-Zuweisung:

%Vor%

Dieser Code läuft auf Glassfish 3.1.1b10 HotSpot 1.6_26 unter Windows 32bit. Ich kann mir keine Erklärung einfallen lassen, warum der erste Block nicht funktioniert!

EDIT / UPDATE 13. Juli 2011:

Zuerst habe ich begonnen, die Glassfish-Domain anzuhalten und sie zwischen Deploys pro Anfrage zu löschen, und dies geschieht immer noch:)

Zweitens kann ich nicht auf Destination oder Consumer synchronisieren, da dies Java EE-Code ist. Aber ich kann versichern, dass Nachrichten verfügbar sind. Es gibt ungefähr 500 von ihnen verfügbar und keine Verbraucher. In der Tat sagt mir ein QueueBrowser, dass es Nachrichten gibt!

Drittens druckt dieses Programm "WORKS!" jedes Mal!!! ARGH !!!

%Vor%

Zuletzt sprach ich über meine eigene Inkompetenz. ;)

    
Jonathan S. Fisher 12.07.2011, 22:26
quelle

4 Antworten

3

Wie Ryan gesagt hat, scheint es eine Wettlaufbedingung zu sein. Die Bytecodes für beide Codes sind die gleichen, mit Ausnahme eines zusätzlichen "astore":

%Vor%

Wenn Sie diese Theorie testen möchten, versuchen Sie diesen Code:

%Vor%

Es ist ein Noop, aber der Bytecode ist fast der gleiche wie der zweite Code (ändert "astore_0" in "astore_1").

Übrigens hatte ich schreckliche Ergebnisse mit "receiveNoWait". Ich bevorzuge "receive (smallTimeout)", um Pufferunterläufe oder ähnliches zu vermeiden.

    
Eduardo Costa 13.07.2011, 17:09
quelle
1

Das klingt für mich wie eine Wettlaufbedingung. Deklaration von Objekten ohne Instanziierung führt immer zu Nullwerten. Sie können glauben, dass im ersten Fall Nachrichten auf Sie warten, aber ich wette, dass es keine gibt. Drucken Sie vor der bedingten Schleife die Anzahl der vorhandenen Objekte aus und überprüfen Sie das resultierende Verhalten. Wenn Sie sich in einer Multithread-Situation befinden, synchronisieren Sie sie gegebenenfalls in der Nachrichtenwarteschlange, um dies zu erleichtern. Ich wette, es funktioniert genau wie erwartet.

    
Ryan 12.07.2011 22:35
quelle
0

Mein Geld ist auf Sie haben nicht den Code ausgeführt, den Sie dachten, Sie wären. Sie erwähnen "läuft auf Glassfish 3.1.1b10", also vermutlich nicht viel in der Art von Komponententests und daher die Fähigkeit, genau zu lokalisieren, wo der Fehler ist, wird schwieriger.

Es gibt ein paar Möglichkeiten, die möglicherweise einen Unterschied in einem bizarren Randfall machen könnten.

  • Es ändert sich subtil auf die Reihenfolge beim Laden von Klassen und Sie tun etwas, was bei der statischen Initialisierung zweifelhaft ist. Ich bin mir nicht einmal sicher, ob das für die Ladereihenfolge von Bedeutung ist.
  • Die null Zuweisung klammert sich an einen Verweis auf dem Stapel, der es erlaubt, ein Objekt zu sammeln, das auf ein Objekt verweist, das mit einer schwachen / soft / phantom / finaliser-Referenz verwendet wird, oder einfach die Speicherzuordnungszeiten ändert und stört eine Wettlaufbedingung.
Tom Hawtin - tackline 12.07.2011 23:24
quelle
0

Ist es möglich, dass Sie angeben, was ein Verbraucher-Objekt sein kann und was das Empfangen von NoWait () sein kann?

    
Ayusman 13.07.2011 11:49
quelle

Tags und Links