用Java中的另一个线程触发线程的方法

时间:2011-10-26 22:11:05

标签: java multithreading

假设我有一个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会在myThreadmain线程中执行吗?
如何从主线程开始在myThread上执行dosomething并检索返回的对象?

5 个答案:

答案 0 :(得分:8)

main(){
    MyThread my = new MyThread().run();    
    Object o = my.dosomething(p);
}
  • 如果这样做,它将无法编译:您正在尝试将void方法void run()的结果分配给类型为MyThread的对象。
  • 实现runnable并调用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()