java 在继续之前等待线程完成
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7518803/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Wait for threads to complete before continuing
提问by Raunak
When the user launches my Android App, I fire up 2 threads to do some processing in the background. thread_1 does some calculations on the client, and thread_2 fetches some data from the server. That all works fine. None of the threads modify the UI. I have two follow up questions.
当用户启动我的 Android 应用程序时,我会启动 2 个线程在后台进行一些处理。thread_1 在客户端做一些计算,thread_2 从服务器获取一些数据。这一切正常。没有任何线程修改 UI。我有两个后续问题。
new Thread(new Runnable(){
@Override
public void run(){
MyClass.someStaticVariable = doSomeCalculations();
}
}).start();
What is the best practice to retrieve the data from the run() method of a thread? I currently have a static variable, and I assign the relavent calculated data/ fetched data to it. Or is it recommended to use the Handler class to get data out of threads? I imagined one only uses the handler if they wish to update the UI.
while(true) { if (!thread1.isAlive() && !thread2.isAlive()) { startActivity(intent) } }
I need to wait until both threads are finished before I can pass the data from both threads via an Intent. How can I achieve that? I can do it using the code shown above, but that just seems wrong.
从线程的 run() 方法检索数据的最佳实践是什么?我目前有一个静态变量,我将相关的计算数据/获取的数据分配给它。还是建议使用Handler类从线程中获取数据?我想只有在他们希望更新 UI 时才使用处理程序。
while(true) { if (!thread1.isAlive() && !thread2.isAlive()) { startActivity(intent) } }
我需要等到两个线程都完成后才能通过 Intent 传递来自两个线程的数据。我怎样才能做到这一点?我可以使用上面显示的代码来完成,但这似乎是错误的。
回答by Joshua
You could use a Future. It will block on get until the data is available: http://developer.android.com/reference/java/util/concurrent/Future.html
你可以使用未来。它会阻塞获取直到数据可用:http: //developer.android.com/reference/java/util/concurrent/Future.html
An alternative is to pass a CountDownLatch into the threads and call countDown() when exiting the run method: http://developer.android.com/reference/java/util/concurrent/CountDownLatch.html
另一种方法是将 CountDownLatch 传递给线程并在退出 run 方法时调用 countDown():http: //developer.android.com/reference/java/util/concurrent/CountDownLatch.html
final CountDownLatch latch = new CountDownLatch(2);
new Thread(new Runnable(){
@Override
public void run(){
// Do something
latch.countDown()
}
}).start();
new Thread(new Runnable(){
@Override
public void run(){
// Do something
latch.countDown()
}
}).start();
latch.await()
startActivity(intent)
回答by gkamal
Using callable / Future / ExecutorService would be the cleanest way of doing this in a reqular java app (should be same for android as well)
使用 callable / Future / ExecutorService 将是在 reqular java 应用程序中执行此操作的最干净的方式(对于 android 也应该相同)
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<Integer> firstThreadResult = executor.submit(new Callable<Integer>() {
Integer call() {
}
});
Future<Integer> secondThreadResult = executor.submit(new Callable<Integer>() {
Integer call() {
}
});
executor.shutdown();
executor.awaitTermination(Integer.MAX_VALUE,TimeUnit.SECONDS); // or specify smaller timeout
// after this you can extract the two results
firstThreadResult.get();
secondThreadResult.get();
More detailed example.
更详细的例子。
回答by Peter Knego
You can use a shared object (via static field pointing to it or any other way), but you must be aware of two things. First there are synchronization issues with objects accessed by two threads. Use immutable objects to aleviate that. Second, how to notify the other thread that new shared data is available - this depends on what your other thread is doing.
Set common flag that both threads check or set when they finish. This way thread can check if other flag finished before it.
您可以使用共享对象(通过指向它的静态字段或任何其他方式),但您必须注意两件事。首先,两个线程访问的对象存在同步问题。使用不可变对象来解决这个问题。其次,如何通知另一个线程新的共享数据可用——这取决于你的另一个线程在做什么。
设置两个线程在完成时检查或设置的公共标志。这样线程可以检查其他标志是否在它之前完成。
回答by Ravindra babu
For query 1:
对于查询 1:
What is the best practice to retrieve the data from the run() method of a thread?
从线程的 run() 方法检索数据的最佳实践是什么?
In addition to Future
, you can use Callback mechanism from your thread run()
method. In this run()
method, pass the value to caller object or set the relevant values in an object.
除了Future
,您还可以使用线程run()
方法的回调机制。在此run()
方法中,将值传递给调用者对象或在对象中设置相关值。
Implementing callbacks in Java with Runnable
For query 2:
对于查询 2:
I need to wait until both threads are finished before I can pass the data from both threads via an Intent
我需要等到两个线程都完成后才能通过 Intent 传递来自两个线程的数据
You can achieve it in multiple ways in addition basic join()
API.
除了基本的join()
API,您还可以通过多种方式实现它。
1.ExecutorServiceinvokeAll()
API
1. ExecutorServiceinvokeAll()
API
Executes the given tasks, returning a list of Futures holding their status and results when all complete.
执行给定的任务,返回一个 Futures 列表,在所有完成时保存它们的状态和结果。
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
一种同步辅助,允许一个或多个线程等待,直到在其他线程中执行的一组操作完成。
3.ForkJoinPoolor newWorkStealingPool()
in Executors
3. ForkJoinPool或 newWorkStealingPool()
在Executors
Refer to this related SE question:
参考这个相关的 SE 问题: