Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
触发器线程';Java中的另一个线程使用的方法_Java_Multithreading - Fatal编程技术网

触发器线程';Java中的另一个线程使用的方法

触发器线程';Java中的另一个线程使用的方法,java,multithreading,Java,Multithreading,假设我有一个类MyThread,它使用dosomething()方法实现Runnable: 如果我这样做: main(){ MyThread my = new MyThread().run(); Object o = my.dosomething(p); } dosomething是在myThread上执行还是在main线程中执行 如何在myThread上从主线程开始执行dosomething,并检索返回的对象?这是不可能的 创建线程时,它在run()中运行代码并退出。

假设我有一个
类MyThread
,它使用
dosomething()方法实现
Runnable

如果我这样做:

main(){
    MyThread my = new MyThread().run();    
    Object o = my.dosomething(p);
}
dosomething
是在
myThread
上执行还是在
main
线程中执行
如何在myThread上从主线程开始执行
dosomething
,并检索返回的对象?

这是不可能的

创建线程时,它在
run()
中运行代码并退出。
没有办法将代码注入到不同的线程中;这将打破核心执行模型。(在一个线程中,代码按顺序运行,中间没有任何内容)

如果愿意,您可以创建一个线程来侦听队列中的回调(
Runnable
instances)并执行它们(如消息循环)。
这就是UI线程的工作方式



而且,你实际上并不是在开始一条线;您需要编写
新线程(someRunnable).start()

它将在主线程上执行,因为调用该方法的是该线程。如果希望
dosomething
在单独的线程中运行,请在
run()
中调用它,并将结果存储在
myThread
字段中,以便以后检索

您可能希望检查
java.util.concurrent
中的类或其他内容,以获得等待结果可用的方便方法

编辑:如果
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;

        }

    }

}

这是一个非常粗糙的方法来处理这个问题。不过,基本概念就在那里。在现实中,你希望使用合适的异步计算,如调用和将来的东西。< /P> < P>听起来你可能想考虑调用和期货。

中有一个不错的解释,例如,您可以使用委托

new MyThread(callWhenFinishObject)
  • 如果这样做,它将无法编译:您试图将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());
        }
    }
}
class-MyClass
{
公共对象doSomething()
{
//返回对象
返回新对象();
}
}
类MyRunnable实现Runnable
{
私人最终MyClass mc;
私有最终对象_锁;
私人最终名单——结果;
公共MyRunnable(MyClass mc、列表结果、对象锁)
{
_mc=mc;
_锁=锁;
_结果=结果;
}
公开募捐
{
已同步(_锁)
{
_结果:添加(_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
    }
}
void main(){
MyClass mc=新的MyClass();
列表结果=新列表();
对象锁=新对象();
//执行线程并等待它完成
线程t=新线程(新MyRunnable(mc、结果、锁));
t、 start();
t、 join();
//得到结果
用于(对象结果:结果)
{
//对结果做点什么
}
}

这应该会让你知道你做错了什么。更现实的例子是,如果你产生多个线程,并发运行它们,然后加入所有线程,直到它们全部完成。

@Skip,请使用正确的命名约定:类名以大写字母开头(例如,
MyThread
而不是
MyThread
)@G_H:是的。他要求在一个单独的已经启动的线程上运行他的方法。我想他只是想启动一个线程以异步方式执行该方法,但控制从主线程在该线程内调用该方法的确切时间。然后在该方法返回后检索该方法的结果。正如其他人指出的,还有很多这不是不可能的。仅仅因为海报的措辞可能有点混乱或者他/她不熟悉Java线程并不意味着我们不应该在字里行间阅读。@G_H:不;他想在
myThread
上运行它,他认为这是一个已经开始的线程。好吧,所以他错了run()方法也是。应该使用start()。更有理由纠正他,对吗?是的;我只是注意到。Thnx,是的,使用
Callables
处理返回值的线程要容易得多。
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
    }
}