I have a method, disconnectUser()
which among other things, assigns null
to an object userSession
at the end of execution. However, a hypothetical arose as I was coming up with the logic, where say userSession
has a running method and it is assigned a null reference while it is still executing; how does the JVM deal with such a situation?
FWIW here are some code snippets for context:
public class A {
UserSession userSession;
/* Skipped irrelevant code
*-------------------------------
*/
private void disconnectUser(){
//Runs an endless while-loop (it's for demonstration's sake)
userSession.runEndlessLoop();
userSession = null;
}
}
ADDENDUM:
Here's the implementation for runEndlessLoop
public void runEndlessLoop(){
Executors.newSingleThreadExecutor().execute(() -> while(true){});
}
userSession
is a reference to an object. You "assign" null
to this reference, not to an object. So you are changing this reference. It doesn't change the object userSession
formerly referenced / pointed to.
Also see: Can unreferenced objects still run if the garbage collector hasn't deleted them?
Let me try to add this: If the method of this object is running in the same thread as the rest of your program, the reference would be changed after this method finishes, so the problem doesn't even come up.
If, in contrast, this object acts in a different thread, well... i just tested it:
public class UnreferencedTest {
public static void main(String[] args) {
UnreferencedTest u = new UnreferencedTest();
u.createObject();
}
private void createObject() {
Unreferenced obj = new Unreferenced();
Thread t = new Thread(obj);//create new thread
t.start();
obj = null; //remove only reference to object
System.gc(); //ask GC to clean up
try {
Thread.sleep(10000); //wait a bit longer than other thread
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private class Unreferenced implements Runnable {
@Override
public void run() {
try {
Thread.sleep(5000);
areYouStillHere();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void areYouStillHere() {
System.out.println("I'm still here!");
}
}
}
... and even "asked" the GC to clean up unreferenced objects. (no guarantee it does!) It's only waiting for 5 seconds, but still runs.
Hope that helps!