java – 捕获当前线程的执行程序

我正在使用Guava的ListenableFuture,关于它们的一个好处是,它将Executor传递给Futures.addCallback方法,即要求在给定的线程/执行器上执行回调.

在我的Android应用程序中,我希望能够在UI线程中基于ListenableFuture启动异步执行,并安排一个也在UI线程上执行的回调.因此,我想以某种方式将UI线程执行程序提交到上面提到的Futures.addCallback方法.怎么实现呢?

或者,换句话说,我想拥有UI线程的执行程序.它是否已经在Android中可用,或者,如果我必须创建自己的,我该怎么做?

编辑:作为这个问题的扩展,是否有可能做同样的事情,但不只是与UI线程,但与任何特定的线程,在哪里调用异步方法?

我很乐意知道如何在不使用像Handler和Looper这样的特定于Android的东西的情况下实现相同的效果,只需使用纯Java.

解决方法:

我想我已经看到了一些实现.基本的想法是粗略的

class UiThreadExecutor implements Executor {
    private final Handler mHandler = new Handler(Looper.getMainLooper());

    @Override
    public void execute(Runnable command) {
        mHandler.post(command);
    }
}

您可以委派在主线程中运行任何东西,方法是将其传递给主线程的处理程序.

编辑:https://github.com/square/retrofit/blob/master/retrofit/src/main/java/retrofit/android/MainThreadExecutor.java例如

Edit2:您可以配置处理程序,例如SensorManager#registerListener(..., Handler handler)允许你这样做.

class HandlerThreadExecutor implements Executor {
    private final Handler mHandler;
    public HandlerThreadExecutor(Handler optionalHandler) {
        mHandler = optionalHandler != null ? optionalHandler : new Handler(Looper.getMainLooper());
    }

    @Override
    public void execute(Runnable command) {
        mHandler.post(command);
    }
}

使用当前线程的looper的优势在于它使您明确使用了Looper.在你的解决方案中,您可以使用任何线程调用新的ExecuteOnCaller()的Looper – 而这通常不是您稍后运行代码的线程.

I would be happy to know how to achieve the same effect without resorting to the Android-specific stuff like Handler and Looper, just with pure Java.

Looper,Handler和所有逻辑背后的消息队列都是由大多数纯Java构成的.通用解决方案的问题在于您无法“注入”代码以运行到线程中.线程必须定期检查某种任务队列,看是否有东西要运行.

如果你写代码

    new Thread(new Runnable() {
        @Override
        public void run() {
            while (!Thread.interrupted()) {
                System.out.println("Hello");
            }
        }
    }).start();

然后没有办法让该线程做任何其他事情,但不断打印“你好”.如果你能做到这一点就像动态地将跳转到其他代码到程序代码中.这将是一个可怕的想法IMO.

    final BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                while (true) {
                    Runnable codeToRunInThisThread = queue.take();
                    codeToRunInThisThread.run();
                }
            } catch (InterruptedException ignored) {}
        }
    }).start();

另一方面,它是一个在队列中永远循环的简单线程.线程可以在其间执行其他任务,但您必须在代码中添加手动检查.

你可以通过它发送任务

    queue.put(new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello!");
        }
    });

这里没有定义特殊的处理程序,但这是Handler& amp;的核心. Looper在Android中做. Android中的Handler允许您为Message定义回调,而不仅仅是Runnable.

Executors.newCachedThreadPool()和类似的东西大致相同.只有多个线程在单个队列中等待代码.

As an extension to this question, is it possible to do same thing, but not just with UI thread, but with any particular thread, where the call to async method is made?

通用答案是否定的.只有在有一种方法可以注入要在该线程中运行的代码时.

上一篇:java_线程池


下一篇:【JUC】5.线程池—Executor