假设我有一个class MyThread
,它使用方法Runnable
实现dosomething()
:
class MyThread implements Runnable{
Object dosomething(Parameter p){ ... }
run(){...};
}
如果我这样做:
main(){
MyThread my = new MyThread().run();
Object o = my.dosomething(p);
}
dosomething
会在myThread
或main
线程中执行吗?
如何从主线程开始在myThread上执行dosomething
并检索返回的对象?
答案 0 :(得分:8)
main(){
MyThread my = new MyThread().run();
Object o = my.dosomething(p);
}
void run()
的结果分配给类型为MyThread
的对象。 run()
不会导致代码在单独的线程中执行,除非您将其传递给另一个线程(即Tread t = new Thread(my);
)如何从主线程开始在myThread上执行dosomething并检索返回的对象?
您可以将doSomething()
的结果存储在稍后可以访问的位置。
class MyClass
{
public Object doSomething()
{
// return the object
return new Object();
}
}
class MyRunnable implements Runnable
{
private final MyClass _mc;
private final object _lock;
private final List<object> _results;
public MyRunnable(MyClass mc, List<object> results, object lock)
{
_mc = mc;
_lock = lock;
_results = results;
}
public void run()
{
synchronized(_lock)
{
_results.add(_mc.doSomething());
}
}
}
现在主要是:
void main(){
MyClass mc = new MyClass();
List<object> results = new List<object>();
object lock = new object();
// Execute your thread and wait for it to complete
Thread t = new Thread(new MyRunnable(mc, results, lock ));
t.start();
t.join();
// Get the results
for(object result:results)
{
// do something with the result
}
}
这应该让你知道你在做什么“错误”。一个更现实的例子是,如果你生成多个线程,同时运行它们然后加入所有线程,直到它们全部完成。
答案 1 :(得分:1)
听起来你可能想要考虑Callables和Futures。 在http://www.vogella.de/articles/JavaConcurrency/article.html#futures
有一个不错的解释答案 2 :(得分:0)
它将在主线程上执行,因为它是调用该方法的线程。如果您希望dosomething
在单独的线程中运行,请在run()
内调用它,并将结果存储在myThread
字段中以供日后检索。
您可能需要检查java.util.concurrent
中的课程Future
或其他内容,以便以一种方便的方式等待结果可用。
编辑:如果dosomething
只应运行,直到满足必须在主线程中标记的某个条件,则run()
阻塞,直到主线程以某种方式通知另一个线程可以继续
编辑2:在这里,有人确认这是被问到的:
package threadtest;
public class Main {
public static void main(final String[] args) {
final MyThread otherThread = new MyThread();
System.out.println("Main thread: I'm gonna start the other thread now...");
otherThread.start();
System.out.println("Main thread: there, hope it does well.");
try {
Thread.sleep(1000); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: I'm gonna do some stuff in the meantime...");
try {
Thread.sleep(200); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: maybe clean up the kitchen.");
try {
Thread.sleep(1000); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: does other thread have something for me yet?");
if(otherThread.getResult() == null)
System.out.println("Main thread: nope, not yet.");
try {
Thread.sleep(500); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
System.out.println("Main thread: oh crap! I forgot to tell it that it may execute its method!");
otherThread.allowToExecute();
System.out.println("Main thread: phew... better keep checking now before it gets angry.");
while(otherThread.getResult() == null) {
try {
Thread.sleep(100); //Lets main thread take a snooze...
} catch(InterruptedException ex) {
//whatever
}
}
System.out.println("Main thread: there we go, it gave me a result. Rest in peace, other thread...");
}
private static class MyThread extends Thread {
private boolean mayExecuteDoSomething = false;
private Object result = null;
@Override
public void run() {
System.out.println("Other thread: whoa, someone started me!");
while(!mayExecuteDoSomething) {
try {
Thread.sleep(100); //I'm gonna sleep for a bit...
} catch(InterruptedException ex) {
//whatever
}
}
System.out.println("Other thread: alright, I'm allowed to execute my method!");
result = doSomething();
System.out.println("Other thread: there, did it. I'll just call it quits now.");
}
public void allowToExecute() {
mayExecuteDoSomething = true;
}
private Object doSomething() {
return new Object();
}
public Object getResult() {
return result;
}
}
}
这是解决这个问题的一种非常粗略的方法。但是,基本概念在那里。实际上,您需要使用Callable和Future之类的东西进行正确的异步计算。
答案 3 :(得分:0)
例如,您可以使用委托。
new MyThread(callWhenFinishObject)
答案 4 :(得分:-2)
这是不可能的。
创建线程时,它会运行run()
中的代码并退出。
没有办法将代码注入到不同的线程中;这将打破核心执行模式。 (在一个线程中,您的代码按顺序运行,两者之间没有任何内容)
如果您愿意,可以创建一个线程来侦听队列中的回调(Runnable
实例)并执行它们(如消息循环)。
这就是UI线程的工作方式。
另外,你实际上并没有开始一个线程;你需要写new Thread(someRunnable).start()