2012-06-13 8 views
7

sage ich folgendes ...Java: Was passiert, wenn eine Runnable, die in einem Thread verwendet wird, auf null gesetzt wird?

// MyRunnable ist eine Klasse, die ich deklariert habe, die Runnable implementiert.

Welche Auswirkungen hat die Einstellung von r auf null, wie ich im obigen Code-Snippet habe?

+0

+1 Werfen Sie einen Blick auf meine Antwort unten :) –

+0

@ Eng.Fouad Brilliant :) Vielen Dank! –

+0

Gern geschehen. Siehe auch meine Antwort hier: http://stackoverflow.com/questions/9404625/java-pass-by-reference/9404727#9404727 –

Antwort

7

Lassen Sie mich über Zahlen Ihnen erklären:

1- Bei

MyRunnable r = new MyRunnable(); 

Sie schaffen neue Instanz der Klasse MyRunnable die meist implementiert Runnable Schnittstelle:

enter image description here

2- Bei

Thread t = new Thread(r); 

Sie einen neuen Thread und Weitergabe von Wert das Objekt zu erzeugen, dass das Referenz r zeigt:

enter image description here

3- Bei

r = null; 

Sie entfernen die Verbindung zwischen der r-Referenz und dem MyRunnable Objekt, das Thread t verwendet, um den Thread auszuführen:

enter image description here

6

Keine Auswirkungen.

Der Thread hat bereits begonnen. Und unabhängig davon behält das Thread-Objekt den Verweis, so dass kein Müll gesammelt wird, bis t dies tut.

+1

Keine Auswirkungen, auch wenn der Thread noch nicht gestartet ist, weil der Thread selbst hat ein Griff auf dem Runnable auch ... – brimborium

+0

@brimborium True. Ich werde klären. – Jivings

3

Nichts.

Die Variable r ist nicht das MyRunnable Objekt selbst; es ist lediglich eine Referenz auf dieses Objekt innerhalb Ihres Codeblocks.

Zunächst erstellen Sie ein neues Objekt MyRunnable. Und dann geben Sie "den Namen" an und weisen ihn der Variablen r zu. Sie übergeben es dann an den Konstruktor Thread (mit der Variablen, um zu beschreiben, über welches Objekt Sie sprechen). Innerhalb dieses Konstruktors wird es fast sicher anderen Referenzen zugewiesen (in dem JDK, das ich verwende, ist es ein Feld mit der Bezeichnung target).

Später verweisen Sie Ihre Referenz r auf ein anderes Objekt - in diesem Fall das Objekt null. Dies hat keine Auswirkungen auf das Objekt es verwendet, um es zu zeigen, nur die Referenz. Ebenso hat es keine Auswirkung auf andere Referenzen, die auf dasselbe Objekt zeigen.

So zeigt der Thread.target Verweis immer noch auf das gleiche MyRunnable Objekt, das Sie ursprünglich erstellt haben, und aus Sicht des Threads hat sich nichts geändert.

Der einzige mögliche Unterschied besteht darin, dass Ihr (äußerer) Code-Snippet keinen Verweis mehr auf das erstellte Objekt hat. Der folgende Code kann daher keine Methoden für dieses Objekt aufrufen oder als Methodenargument usw. übergeben. (Dies sollte kein Problem sein - oder überraschend - da Sie Ihre einzige Referenz auf dieses Objekt absichtlich aufgehoben haben!

)

Wenn nichts einen Verweis auf ein bestimmtes Objekt hält, dann wird die Garbage Collector bei der nächsten Ausführung wird das Objekt nicht erreichbar betrachten, und es zu sammeln. Dies ist jedoch selten etwas, über das Sie sich Gedanken machen müssen, denn wenn Sie keinen Bezug zum Objekt haben, könnten Sie sowieso nichts damit machen (das ganze Prinzip hinter GC).

In diesem Fall wird MyRunnable nicht als GCed angezeigt, da der Thread immer noch einen Verweis darauf enthält.

Das heißt, wenn der Konstruktor sich anders verhalten waren und nicht eine Referenz zu speichern, weil es nicht ein brauchte (vielleicht auch nur verwendet es die toString() Darstellung), dann wäre das Objekt nicht erreichbar angesehen werden, und würde gesammelt werden .In beiden Fällen würde der Garbage Collector das Richtige tun - ein Objekt nur dann und nur dann sammeln, wenn sich nichts mehr darauf bezieht - ohne dass Sie sich darum kümmern oder in Ihrem Code Bescheid wissen müssen.