Java 使用正在运行的方法将null赋值给对象
我有一个方法disconnectUser,它在执行结束时将null分配给对象userSession。然而,在我提出逻辑时出现了一个假设,假设userSession有一个正在运行的方法,并且在它仍在执行时被分配了一个空引用;JVM如何处理这种情况 FWIW以下是上下文的一些代码片段: 增编: 下面是runEndlessLoop的实现 userSession是对对象的引用。将null指定给此引用,而不是对象。所以您正在更改此引用。它不会更改以前引用/指向的对象userSession 另见: 让我试着补充一点:如果这个对象的方法与程序的其余部分在同一个线程中运行,那么在这个方法完成后,引用将被更改,所以问题就不会出现。 相反,如果这个对象在不同的线程中运行,那么。。。我刚刚测试过:Java 使用正在运行的方法将null赋值给对象,java,Java,我有一个方法disconnectUser,它在执行结束时将null分配给对象userSession。然而,在我提出逻辑时出现了一个假设,假设userSession有一个正在运行的方法,并且在它仍在执行时被分配了一个空引用;JVM如何处理这种情况 FWIW以下是上下文的一些代码片段: 增编: 下面是runEndlessLoop的实现 userSession是对对象的引用。将null指定给此引用,而不是对象。所以您正在更改此引用。它不会更改以前引用/指向的对象userSession 另见: 让我试着
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!");
}
}
}
。。。甚至要求GC清理未引用的对象。不一定!它只等了5秒钟,但仍在运行
希望有帮助 是的,听起来像是等待发生的内存泄漏……无论如何,如果您运行一个无止境的循环,您将永远不会执行将null分配给usersession的行,如果它不是无止境的,那么当您将null分配给usersession时,您将不再处于usersession中的方法中reference@ErwinBolwidt好主意,让我来解决,换句话说,这些对象在后台继续执行,直到完成后才会被垃圾收集?@Garikai我添加了一些解释和示例代码来处理!这是您提出的一个非常有用的测试用例谢谢,但是我的代码错了!我把它改成了一个新的线程,但我忘了这么做。。。现在这个物体似乎仍然在做它的工作。
public void runEndlessLoop(){
Executors.newSingleThreadExecutor().execute(() -> while(true){});
}
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!");
}
}
}