java - Guava 中的 ListenableFuture 将在哪个线程中调用 FutureCallback?

标签 java android multithreading guava

我一定是漏掉了什么。我很难理解将在哪个线程中为 Guava 中的 ListenableFuture 调用 FutureCallback。

我的代码的第一个版本是:

    Log.d("mydebug", "Before submit, " + Thread.currentThread() + ", " + android.os.Process.myTid());
    ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
    ListenableFuture future = service.submit(new Runnable() {
        @Override
        public void run() {
            Log.d("mydebug", "In run, " + Thread.currentThread() + ", " + android.os.Process.myTid());
        }
    });

    Futures.addCallback(future, new FutureCallback() {
        @Override
        public void onSuccess(Object result) {
            Log.d("mydebug", "In onSuccess, " + Thread.currentThread() + ", " + android.os.Process.myTid());
        }
        @Override
        public void onFailure(Throwable thrown) {
            Log.d("mydebug", "In onFailure, " + Thread.currentThread() + ", " + android.os.Process.myTid());
        }
    }, MoreExecutors.sameThreadExecutor());

我的代码的第一个版本的输出是:

02-04 12:37:00.815 11327 11327 D mydebug : Before submit, Thread[main,5,main], 11327
02-04 12:37:00.825 11327 11382 D mydebug : In run, Thread[pool-1-thread-1,5,main], 11382
02-04 12:37:00.825 11327 11327 D mydebug : In onSuccess, Thread[main,5,main], 11327

我将 Thread.sleep 添加到 Runnable 中以制作我的代码的第二个版本:

    Log.d("mydebug", "Before submit, " + Thread.currentThread() + ", " + android.os.Process.myTid());
    ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
    ListenableFuture future = service.submit(new Runnable() {
        @Override
        public void run() {
            Log.d("mydebug", "In run, " + Thread.currentThread() + ", " + android.os.Process.myTid());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });

    Futures.addCallback(future, new FutureCallback() {
        @Override
        public void onSuccess(Object result) {
            Log.d("mydebug", "In onSuccess, " + Thread.currentThread() + ", " + android.os.Process.myTid());
        }
        @Override
        public void onFailure(Throwable thrown) {
            Log.d("mydebug", "In onFailure, " + Thread.currentThread() + ", " + android.os.Process.myTid());
        }
    }, MoreExecutors.sameThreadExecutor());

第二版代码的输出是:

02-04 12:43:02.165 17180 17180 D mydebug : Before submit, Thread[main,5,main], 17180
02-04 12:43:02.205 17180 17229 D mydebug : In run, Thread[pool-1-thread-1,5,main], 17229
02-04 12:43:04.215 17180 17229 D mydebug : In onSuccess, Thread[pool-1-thread-1,5,main], 17229

所以在我的第一个版本的代码中,FutureCallback 是在调用 service.submit 的线程中执行的,而我的第二个版本的代码中,FutureCallback 是在线程池中的一个线程中执行的。我很困惑。 MoreExecutors.sameThreadExecutor() 到底是什么意思?它没有像我预期的那样工作。

最佳答案

这里的文档非常明确:

Note: If the callback is slow or heavyweight, consider supplying an executor. If you do not supply an executor, addCallback will use a direct executor [note: this is equivalent to sameThreadExecutor() which you passed in explicitly], which carries some caveats for heavier operations. For example, the callback may run on an unpredictable or undesirable thread:

  • If the input Future is done at the time addCallback is called, addCallback will execute the callback inline. [that is, directly in the call to addCallback on the same thread where addCallback was called]

  • If the input Future is not yet done, addCallback will schedule the callback to be run by the thread that completes the input Future, which may be an internal system thread such as an RPC network thread.

请注意“直接执行器”是执行器的最简单可能实现:

   final class DirectExecutor implements Executor {
     public void execute(Runnable r) {
       r.run();
     }
   }

关于java - Guava 中的 ListenableFuture 将在哪个线程中调用 FutureCallback?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35211331/

相关文章:

java - 处理构造函数逻辑的工厂类?

multithreading - 什么样的应用程序需要多线程?

java - kill -3 获取java线程转储

Java,可见性和无限循环发生

java - netty EpollEventLoopGroup vs NioEventLoopGroup,我应该在 CentOS 6 上选择哪个?

android - Kotlin:可空属性委托(delegate)可观察

android - RecyclerView 动态标题

java - 创建 50 个线程连接到服务器以进行负载测试

java - 如何在 java 文件管理器应用程序中重命名文件和文件夹?

android - 如何设置 EditText 自定义光标可绘制?