Java 使用正在运行的方法将null赋值给对象

Java 使用正在运行的方法将null赋值给对象,java,Java,我有一个方法disconnectUser,它在执行结束时将null分配给对象userSession。然而,在我提出逻辑时出现了一个假设,假设userSession有一个正在运行的方法,并且在它仍在执行时被分配了一个空引用;JVM如何处理这种情况 FWIW以下是上下文的一些代码片段: 增编: 下面是runEndlessLoop的实现 userSession是对对象的引用。将null指定给此引用,而不是对象。所以您正在更改此引用。它不会更改以前引用/指向的对象userSession 另见: 让我试着

我有一个方法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!");
        }
    }

}