如何承诺完成多个线程?
How to promise completion of multiple threads?
我对 java 中的多线程概念有点陌生。
这个问题的标题可能与之前关于该主题的问题有相似之处,但尽管查看了答案,我仍然成功地完成了以下工作:
在 MainActivity 上说我有一个嵌套的 for 循环。在内部循环中,我是 运行 来自另一个 class 的方法,它采用接口作为回调,如下所示:
MainActivity.java
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_display_prices, container, false);
return v;
for (i = 0; i < 10; i++) {
for (i = 0; i < 4; i++){
CategoryItemsDataSource.getCategoryItemsData(url, new CategoryItemsDataSource.OnCategoryItemsDataArrived() {
@Override
public void onCategoryItemsDataArrived(List<ProductItem> data, Exception e) {
getActivity.runOnUiThread(new Runnable() {
//display retrieved data on UIThread...
});
}
});
}
}
}
CategoryItemDataSource.java
public class CategoryItemsDataSource {
public interface OnCategoryItemsDataArrived {
void onCategoryItemsDataArrived(List<ProductItem> data, Exception e);
}
public static void getCategoryItemsData(final String[] url, final OnCategoryItemsDataArrived listener){
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(new Runnable() {
@Override
public void run() {
try {
List<ProductItem> data = new ArrayList<>();
//retreiving data from web and appending to List<> Data....
}
listener.onCategoryItemsDataArrived(data, null);
} catch (Exception e) {
e.printStackTrace();
listener.onCategoryItemsDataArrived(null, e);
}
}
});
service.shutdown();
}
我不知道如何从 MainActivity 中的 CategoryItemDataSource class [I.E 如果我需要的话] 访问 ExecutorService 实例。因此,我该如何 ensure/promise 完成内部循环中生成的所有线程?
创建一个计数器变量;在循环中,每次将新任务提交给执行程序时递增计数器。在 onCategoryItemsDataArrived
方法中,递减该计数器;当它变为零时,所有任务都已完成。提供对计数器的原子访问:使用 AtomicInteger
或 synchronized
语句。
I don't know how to access the ExecutorService instance from the CategoryItemDataSource class [I.E if I need to at all], in the MainActivity. hence, how am I suppose to ensure/promise completion of all the several threads generated in the inner loop?
有几种方法可以做到这一点,但最好的方法是 getCategoryItemsData(...)
方法 return Future
对象 return 由 [=13] =] 命令(与 service.execute(...)
相反)。然后,您可以将这些 Future
保存在一个数组中,然后对它们调用 future.get(...)
以等待它们完成。如果您自己管理线程,这样做类似于调用 thread.join()
。
类似于:
int numJobs = 4;
// this might need to be Future<Void> or something
Future<?>[] futures = new Future<>[numJobs];
for (i = 0; i < numJobs; i++) {
futures[i] = CategoryItemsDataSource.getCategoryItemsData(...);
}
for (Future<?> future : futures) {
// waits for each of the jobs to finish, you'll need to handle the exceptions
future.get();
}
但有一点很奇怪,您每次都在创建一个新的 ExecutorService
。我怀疑你想这样做。我会在 CategoryItemsDataSource
中创建一个服务作为字段,然后让每个 getCategoryItemsData(...)
调用将他们的作业提交到同一服务。
我对 java 中的多线程概念有点陌生。
这个问题的标题可能与之前关于该主题的问题有相似之处,但尽管查看了答案,我仍然成功地完成了以下工作:
在 MainActivity 上说我有一个嵌套的 for 循环。在内部循环中,我是 运行 来自另一个 class 的方法,它采用接口作为回调,如下所示:
MainActivity.java
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_display_prices, container, false);
return v;
for (i = 0; i < 10; i++) {
for (i = 0; i < 4; i++){
CategoryItemsDataSource.getCategoryItemsData(url, new CategoryItemsDataSource.OnCategoryItemsDataArrived() {
@Override
public void onCategoryItemsDataArrived(List<ProductItem> data, Exception e) {
getActivity.runOnUiThread(new Runnable() {
//display retrieved data on UIThread...
});
}
});
}
}
}
CategoryItemDataSource.java
public class CategoryItemsDataSource {
public interface OnCategoryItemsDataArrived {
void onCategoryItemsDataArrived(List<ProductItem> data, Exception e);
}
public static void getCategoryItemsData(final String[] url, final OnCategoryItemsDataArrived listener){
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(new Runnable() {
@Override
public void run() {
try {
List<ProductItem> data = new ArrayList<>();
//retreiving data from web and appending to List<> Data....
}
listener.onCategoryItemsDataArrived(data, null);
} catch (Exception e) {
e.printStackTrace();
listener.onCategoryItemsDataArrived(null, e);
}
}
});
service.shutdown();
}
我不知道如何从 MainActivity 中的 CategoryItemDataSource class [I.E 如果我需要的话] 访问 ExecutorService 实例。因此,我该如何 ensure/promise 完成内部循环中生成的所有线程?
创建一个计数器变量;在循环中,每次将新任务提交给执行程序时递增计数器。在 onCategoryItemsDataArrived
方法中,递减该计数器;当它变为零时,所有任务都已完成。提供对计数器的原子访问:使用 AtomicInteger
或 synchronized
语句。
I don't know how to access the ExecutorService instance from the CategoryItemDataSource class [I.E if I need to at all], in the MainActivity. hence, how am I suppose to ensure/promise completion of all the several threads generated in the inner loop?
有几种方法可以做到这一点,但最好的方法是 getCategoryItemsData(...)
方法 return Future
对象 return 由 [=13] =] 命令(与 service.execute(...)
相反)。然后,您可以将这些 Future
保存在一个数组中,然后对它们调用 future.get(...)
以等待它们完成。如果您自己管理线程,这样做类似于调用 thread.join()
。
类似于:
int numJobs = 4;
// this might need to be Future<Void> or something
Future<?>[] futures = new Future<>[numJobs];
for (i = 0; i < numJobs; i++) {
futures[i] = CategoryItemsDataSource.getCategoryItemsData(...);
}
for (Future<?> future : futures) {
// waits for each of the jobs to finish, you'll need to handle the exceptions
future.get();
}
但有一点很奇怪,您每次都在创建一个新的 ExecutorService
。我怀疑你想这样做。我会在 CategoryItemsDataSource
中创建一个服务作为字段,然后让每个 getCategoryItemsData(...)
调用将他们的作业提交到同一服务。