CompletableFuture.thenAccept中使用的垃圾收集对象的可用性

Har*_*dhu 1 java concurrency asynchronous java-8 completable-future

我试图从使用的方法执行异步调用CompletableFuture.完成该任务后,我试图打印对象DummyObject的值,这些对象是调用异步调用的方法的本地对象.

我想知道它是如何工作的?thread(myThread)在3秒后死亡,DummyObject超出范围,thenAccept中的Async回调仍然打印正确的值.线程是否在DummyObject上获得锁定?或者其他事情正在发生?

请注意,我只是想模拟一个场景.所以我正在使用Thread.stop().

编辑 - 问题是关于thenAccept Consumer如何处理范围?请保持与此相关的答案.

以下计划的输出:

Starting Async stuff
Thread Alive?  false
Reached Main end and waiting for 8 more seconds
James T. Kirk
United Federation of Planets
Run Code Online (Sandbox Code Playgroud)

AsyncTest.java

public class AsyncTest {

    public static void main(String args[]) {

        Thread myThread = new Thread() {
            @Override
            public void run() {
                DummyObject dummyObj = new DummyObject();
                dummyObj.setObjectName("James T. Kirk");
                dummyObj.setObjectNationality("United Federation of Planets");
                System.out.println("Starting Async stuff");
                new AsyncTaskExecuter().executeAsync().thenAccept(taskStatus -> {
                    if(taskStatus.booleanValue()) {
                        System.out.println(dummyObj.getObjectName());
                        System.out.println(dummyObj.getObjectNationality());
                    }
                });
            }
        };

        myThread.start();
        try {
            Thread.sleep(3 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        myThread.stop();
        System.out.println("Thread Alive?  "+ myThread.isAlive());

        System.out.println("Reached Main end and waiting for 8 more seconds");

        try {
            Thread.sleep(8 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

class AsyncTaskExecuter {
    public CompletableFuture<Boolean> executeAsync() {
        return  (CompletableFuture<Boolean>) CompletableFuture.supplyAsync(this::theTask);
    }

    public Boolean theTask() {
        try {
            Thread.sleep(6 * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return true;
    }
}

class DummyObject {
    private String objectName;
    private String objectNationality;
    // getters and setters
}
Run Code Online (Sandbox Code Playgroud)

Sne*_*neh 5

第一件事.请不要使用stop()方法.它已被弃用.一旦完成执行run方法,线程就会自行消亡.

现在回答你的问题,当你创建一个CompletableFuture时,它还会在java中创建一个线程ForkJoinCommonPool并在将来的某个时间执行它.在您的应用程序中有效地创建3个线程.所以你的对象不能死,因为它将被其中一个线程使用.

  1. 主线程
  2. 我的多线程
  3. 最后一个是CompletableFuture创建的.(这将使用虚拟对象)

所以即使线程1,2死亡.线程3仍将执行.

在此输入图像描述

PS我给你的线程命名为Thread-MyThread来向你展示线程.您可以通过调用Thread的构造函数给线程命名,该构造函数将线程的名称作为参数.我使用的工具是JVisualVM.

  • 是的,他不应该创建那个线程.没有必要这样做. (2认同)
  • 我猜它*会给那些虚拟对象提供有限的范围,但是将它们放在任何方法中都是如此. (2认同)
  • @Stephen C回答了另一部分:) (2认同)