我在Android应用中创建了一个DataBaseManager
类,用于管理我应用的所有数据库操作。
我有不同的方法来从数据库创建,更新和检索值。
我在runnable上执行此操作并将其提交给线程池执行程序。
如果我必须从这个Runnable
返回一些值,我怎么能实现它,我知道回调但是对于我而言,由于方法的数量很大,这对我来说会很麻烦。
任何帮助将不胜感激!
答案 0 :(得分:3)
您需要使用Callable :Interface Callable<V>
使用它与 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();
}
}