Eu tenho um método, disconnectUser()
que entre outras coisas, atribui null
a um objeto userSession
no final da execução. No entanto, uma hipotética surgiu quando eu estava chegando com a lógica, onde digamos userSession
tem um método de execução e que é atribuída uma referência nula enquanto ele ainda está em execução; como é que o negócio JVM com tal situação, um?
FWIW, aqui estão alguns trechos de código para contexto:
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;
}
}
TERMO ADITIVO:
Aqui está a implementação para runEndlessLoop
public void runEndlessLoop(){
Executors.newSingleThreadExecutor().execute(() -> while(true){});
}
userSession
é uma referência a um objecto. Você "Atribuir" null
para esta referência, não a um objeto. Então, você está mudando esta referência. Isso não muda o objeto userSession
anteriormente referenciado / apontado.
Veja também: Can objetos não referenciados ainda executado se o coletor de lixo não tenha excluído?
Deixe-me tentar acrescentar o seguinte: Se o método deste objeto está sendo executado no mesmo segmento como o resto do seu programa, a referência seria alterada após este método acabamentos, assim que o problema nem sequer vir para cima.
Se, ao contrário, este objeto atua em um segmento diferente, bem ... eu só testei:
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!");
}
}
}
... e até mesmo "pediu" o GC para limpar objetos não referenciados. (Nenhuma garantia de que ele faz!) Ele só espera de 5 segundos, mas ainda corre.
Espero que ajude!