在Thread Pool Executor中从Runnables返回值的最简单有效的方法是什么?

时间:2013-10-21 12:34:58

标签: java threadpool

我在Android应用中创建了一个DataBaseManager类,用于管理我应用的所有数据库操作。

我有不同的方法来从数据库创建,更新和检索值。

我在runnable上执行此操作并将其提交给线程池执行程序。

如果我必须从这个Runnable返回一些值,我怎么能实现它,我知道回调但是对于我而言,由于方法的数量很大,这对我来说会很麻烦。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:3)

您需要使用Callable Interface Callable<V>

  1. Runnable 类似,它的实例可能由另一个线程执行。
  2. 但更聪明的是 Runnable :能够返回结果并检查异常
  3. 使用它与 Runnable

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

    我使用T来表示引用类型,例如String

    完成后获得结果:

    • using Future<V>:未来代表了一个结果 异步计算。提供方法来检查是否 计算完成,等待其完成。结果是 在计算完成时使用方法 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
      

      上述方法的缺点是,如果第一个任务需要一个 很长时间计算和所有其他任务在第一个之前结束, 当前线程无法在第一个任务之前计算结果 结束。因此,另一种解决方案是使用 CompletionService

    • using CompletionService<V>:一种解耦的服务 从消费中产生新的异步任务 完成任务的结果。生产者提交执行任务。 消费者完成任务并按顺序处理结果 他们完成了。使用它很简单如下:

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

      然后使用 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
        }
      

答案 1 :(得分:1)

以下是使用可调用

的示例代码
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();
        }
    }