![](/img/trans.png)
[英]How to pass the object back to Main thread from another threads in Android?
[英]In Java, how to pass the objects back to Main thread from worker threads?
Java,如何将对象从工作线程传回主线程? 以下面的代码为例:
main(String[] args) {
String[] inputs;
Result[] results;
Thread[] workers = new WorkerThread[numThreads];
for (int i = 0; i < numThreads; i++) {
workers[i] = new WorkerThread(i, inputs[i], results[i]);
workers[i].start();
}
....
}
....
class WorkerThread extends Thread {
String input;
int name;
Result result;
WorkerThread(int name, String input, Result result) {
super(name+"");
this.name = name;
this.input = input;
this.result = result;
}
public void run() {
result = Processor.process(input);
}
}
如何将result
传递回main
的results[i]
?
将this
传递给WorkerThread
怎么样,
workers[i] = new WorkerThread(i, inputs[i], results[i], this);
这样它就可以
mainThread.reults[i] = Processor.process(inputs[i]);
为什么不使用Callable
和ExecutorService
?
main(String[] args) {
String[] inputs;
Future<Result>[] results;
for (int i = 0; i < inputs.length; i++) {
results[i] = executor.submit(new Worker(inputs[i]);
}
for (int i = 0; i < inputs.length; i++) {
Result r = results[i].get();
// do something with the result
}
}
一种解决方法是在WorkerThread
使用回调:
class WorkerThread extends Thread {
ICallback callback;
...
WorkerThread(int name, String input, Result result, ICallback callback) {
super(name+"");
this.callback = callback;
...
}
public void run() {
result = Processor.process(input);
callback.addResult(result);
}
}
您的调用类将在其中实现addResult
并将其添加到result
数组。
@Thilo和@Erickson的答案是最好的答案。 现有的API可以简单可靠地完成这种事情。
但是,如果您想坚持当前的手工方法,那么对您的代码进行以下更改可能就足够了:
for (int i = 0; i < numThreads; i++) {
results[i] = new Result();
...
workers[i] = new WorkerThread(i, inputs[i], results[i]);
workers[i].start();
}
...
public void run() {
Result tmp = Processor.process(input);
this.result.updateFrom(tmp);
// ... where the updateFrom method copies the state of tmp into
// the Result object that was passed from the main thread.
}
另一种方法是用Result[]
替换主程序中的Result[][]
并将Result[0]
传递到可以用结果对象更新的子线程。 (轻巧的支架)。
但是,当您在较低级别实现此功能时,有一个重要提示 ,即主线程需要在尝试检索结果之前在所有子线程上调用Thread.join。 如果您不这样做,则存在主线程偶尔会在Result对象中看到陈旧值的风险。 join
还确保main
线程在相应的子线程完成结果之前不会尝试访问它。
主线程将需要等待工作线程完成才能获取结果。 一种方法是让主线程在尝试读取结果之前等待每个工作线程终止。 线程在其run()方法完成时终止。
例如:
for (int i = 0; i < workers.length; i++) {
worker.join(); // wait for worker thread to terminate
Result result = results[i]; // get the worker thread's result
// process the result here...
}
您仍然必须安排将工作线程的结果以某种方式插入到result []数组中。 作为一种可能性,您可以通过在每个工作线程中传递数组和索引,并让工作线程在终止之前分配结果来实现。
一些典型的解决方案是:
Runnable
或Thread
)。 这类似于使用Future
接口。 BlockingQueue
,可以将其放入结果中。 ExecutorService
和Callable
接口即可获取一个Future
,可以要求它提供结果。 看来您的目标是并行执行计算,然后一旦所有结果可用于主线程,它便可以继续并使用它们。
如果是这样,请将并行计算实现为Callable
而不是线程。 将此任务集合传递给ExecutorService
的invokeAll()
方法。 该方法将阻塞,直到所有任务都完成,然后您的主线程才能继续。
我认为我有一个更好的解决方案,为什么不让工作线程将结果传递给linkedListBlockingQueue,完成后传递给他们,而您的主函数则从队列中选择结果
while(true){linkedListBlockingQueue.take();
//todo: fil in the task you want it to do
//if a specific kind of object is returned/countdownlatch is finished exit
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.