简体   繁体   English

在线程池执行器中从Runnables返回值的最简单,最有效的方法是什么?

[英]what is the most simple and efficient way to return value from Runnables in Thread Pool Executor?

I have created a DataBaseManager Class in my android app that manages all database operations for my app. 我在我的Android应用程序中创建了一个DataBaseManager类,该类管理我的应用程序的所有数据库操作。

I have different methods to create,update, and retrieve value from database. 我有不同的方法来创建,更新和从数据库检索值。

I do it on a runnable and submit it to the Thread pool Executor. 我在可运行对象上执行此操作,然后将其提交给线程池执行程序。

In case, I have to return some value from this Runnable , how can I achieve it, I know about callbacks but it will be little cumbersome for me as the number of methods large. 以防万一,我必须从Runnable返回一些值,我该如何实现它,我知道回调,但是随着方法数量的增加,这对我来说并不麻烦。

Any help will be appreciated! 任何帮助将不胜感激!

You need to use Callable : Interface Callable<V> 您需要使用CallableInterface Callable<V>

  1. Like Runnable , It's instances are potentially executed by another thread. Runnable一样,它的实例可能由另一个线程执行。
  2. But smarter then Runnable : Capable of returning result and checked Exception 但是比Runnable更聪明:能够返回结果并检查Exception

Using it is as much simple as Runnable : 使用它与Runnable一样简单:

private final class MyTask extends Callable<T>{
  public T call(){
     T t;
    // your code
       return t;
    }
}

I am using T to represent a reference type eg String . 我使用T表示引用类型,例如String

Getting the result upon completion: 完成时获取结果:

  • using Future<V> : A Future represents the result of an asynchronous computation. using Future<V> :Future表示异步计算的结果。 Methods are provided to check if the computation is complete, to wait for its completion. 提供了一些方法来检查计算是否完成,以等待其完成。 The result is retrieved using method get() when the computation has completed, blocking if necessary until it is ready. 计算完成后,使用get()方法检索结果,必要时将其阻塞,直到准备就绪为止。

      List<Future<T>> futures = new ArrayList<>(10); for(int i = 0; i < 10; i++){ futures.add(pool.submit(new MyTask())); } T result; for(Future<T> f: futures) result = f.get(); // get the result 

    The disadvantages of above approach is that, if first task takes a long time to compute and all the other tasks ends before the first, the current thread cannot compute the result before the first task ends. 上述方法的缺点是,如果第一个任务需要很长时间来计算,而所有其他任务在第一个任务之前结束,则当前线程无法在第一个任务结束之前计算结果。 Hence another solution would be to use CompletionService . 因此,另一个解决方案是使用CompletionService

  • using CompletionService<V> : A service that decouples the production of new asynchronous tasks from the consumption of the results of completed tasks. using CompletionService<V> :一种服务,该服务将新异步任务的产生与完成任务的结果的消耗分开。 Producers submit tasks for execution. 生产者提交任务以执行。 Consumers take completed tasks and process their results in the order they complete. 消费者执行已完成的任务,并按完成顺序处理结果。 Using it is as simple as follows: 使用它很简单,如下所示:

     CompletionService<T> pool = new ExecutorCompletionService<T>(threadPool); 

    And then use pool.take().get() to read the returned result from callable instances: 然后使用pool.take()。get()从可调用实例中读取返回的结果:

      for(int i = 0; i < 10; i++){ pool.submit(new MyTask()); } for(int i = 0; i < 10; i++){ T result = pool.take().get(); //your another code } 

the below is the sample code for using callable 以下是使用Callable的示例代码

import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

    public class Test {
        public static void main(String[] args) throws Exception {
            ExecutorService executorService1 = Executors.newFixedThreadPool(4);     

            Future f1 =executorService1.submit(new callable());
            Future f2 =executorService1.submit(new callable());     
            System.out.println("f1 " + f1.get());
            System.out.println("f1 " + f2.get());

            executorService1.shutdown();
        }

    }


    class callable implements Callable<String> {
        public String call() {
             System.out.println(" Starting callable Asynchronous task" + Thread.currentThread().getName());
             try {
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {          
                e.printStackTrace();
            }
            System.out.println(" Ending callable Asynchronous task" +  Thread.currentThread().getName());
            return Thread.currentThread().getName();
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM