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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7909553/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 21:57:16  来源:igfitidea点击:

Trigger thread's method by another thread in Java

javamultithreading

提问by Skip

Supposed I have a class MyThread, which implements Runnablewith a method dosomething():

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

class MyThread implements Runnable{
    Object dosomething(Parameter p){ ... }    
    run(){...};
}

If I do:

如果我做:

main(){
    MyThread my = new MyThread().run();    
    Object o = my.dosomething(p);
}

will dosomethingbe executed on myThreador in the mainThread?
How can I start the execution of dosomethingon myThread from the main Thread and retrieve the returned Object?

将在线程dosomethingmyThreadmain线程中执行?
如何dosomething从主线程开始在 myThread 上执行并检索返回的对象?

回答by Kiril

main(){
    MyThread my = new MyThread().run();    
    Object o = my.dosomething(p);
}
  • If you do that it won't compile: you're trying to assign the result of a void method, void run(), to an object of type MyThread.
  • Implementing runnable and calling run()will not cause the code to be executed in a separate thread unless you pass it to another thread (i.e. Tread t = new Thread(my);)
  • 如果这样做,它将无法编译:您试图将 void 方法的结果 , 分配给void run()类型为 的对象MyThread
  • 实现 runnable 和调用run()不会导致代码在单独的线程中执行,除非您将其传递给另一个线程(即Tread t = new Thread(my);


How can I start the execution of dosomething on myThread from the main Thread and retrieve the returned Object?

如何从主线程开始在 myThread 上执行 dosomething 并检索返回的对象?

You do that by storing the result of doSomething()in a location where you can access it later.

为此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());
        }
    }
}

So now in main:

所以现在主要是:

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
    }
}

This should give you an idea of what you're doing "wrong." A more realistic example would be if you spawn multiple threads, run them concurrently and then join on all of them until they all complete.

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

回答by GreyBeardedGeek

Sounds like you may want to consider Callables and Futures. There's a decent explanation at http://www.vogella.de/articles/JavaConcurrency/article.html#futures

听起来您可能想要考虑 Callables 和 Futures。http://www.vogella.de/articles/JavaConcurrency/article.html#futures有一个不错的解释

回答by IronBCC

You can use delegate, for example.

例如,您可以使用委托。

new MyThread(callWhenFinishObject)

回答by G_H

It'll be executed on the main thread, since it's that thread that calls the method. If you want dosomethingto run in the separate thread, have it called within run()and store the result in a myThreadfield for later retrieval.

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

You might want to check class Futureor other stuff in java.util.concurrentfor some convenient way of waiting for the result to become available.

您可能需要检查类Future或其他内容,java.util.concurrent以方便地等待结果可用。

EDIT: if dosomethingshould only run until some condition is satisfied that must be flagged in the main thread, have run()block until the main thread somehow signals the other thread that it's okay to go on.

编辑:如果dosomething应该只运行直到满足必须在主线程中标记的某些条件,则run()阻塞直到主线程以某种方式向另一个线程发出可以继续的信号。

EDIT 2: here, someone confirm this is what's being asked:

编辑 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;

        }

    }

}

This is a very crude approach to the issue. The basic concepts are there, though. In reality, you'd want to use stuff like Callable and Future for proper asynchronous computation.

这是对这个问题的一种非常粗略的方法。但是,基本概念就在那里。实际上,您希望使用 Callable 和 Future 之类的东西来进行适当的异步计算。

回答by SLaks

That is not possible.

这是不可能的。

When you create a thread, it runs the code in run()and exits.
There is no way to inject code into a different thread; that would break the core execution model. (Within a thread, your code runs sequentially, with nothing in between)

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

If you want to, you can create a thread that listens for callback (Runnableinstances) in a queue and executes them (like a message loop).
This is how the UI thread works.

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



Also, you aren't actually startign a thread; you need to write new Thread(someRunnable).start()

此外,您实际上并没有启动线程;你需要写new Thread(someRunnable).start()