java 无需等待即可调用函数

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

Call a function without waiting for it

javapythonfunctionmethods

提问by Abs

Hi I was wondering if there was a way of calling a function/method (preferably in Python or Java) and continue execution without waiting for it.

嗨,我想知道是否有一种方法可以调用函数/方法(最好在 Python 或 Java 中)并继续执行而无需等待。

Example:

例子:

def a():
    b()  #call a function, b()
    return "something"

def b():
    #something that takes a really long time

回答by Ashwin Singh

Run it in a new thread. Learn about multithreading in java hereand python multithreading here

在新线程中运行它。了解在Java多线程这里和python多线程这里

Java example:

Java示例:

The WRONG way ... by subclassing Thread

错误的方式......通过子类化Thread

new Thread() {
    public void run() {
        YourFunction();//Call your function
    }
}.start();

The RIGHT way ... by supplying a Runnable instance

正确的方法......通过提供一个 Runnable 实例

Runnable myrunnable = new Runnable() {
    public void run() {
        YourFunction();//Call your function
    }
}

new Thread(myrunnable).start();//Call it when you need to run the function

回答by jsbueno

As noted in other answers, from Python you can either put the function in a new thread (not that good, since threads in CPython do not gain you much), or in another process using Multiprocessing -

正如其他答案中所指出的,从 Python 中,您可以将函数放在一个新线程中(不是很好,因为 CPython 中的线程不会给您带来太多好处),或者在另一个使用 Multiprocessing 的进程中 -

from multiprocessing import Process

def b():
    # long process

def a():
    p = Process(target=b) 
    p.start()
    ...
a()

(As put in monkut's answer).

(正如在monkut的回答中所说的那样)。

But Python's decorator allow one to hide the boilerplate under the carpet, in a way that at calling time, you "see" just a normal function call. In the example bellow, I create the "parallel" decorator - just place it before any function, and it will authomatically run in a separate process when called:

但是 Python 的装饰器允许人们将样板隐藏在地毯下,在调用时,您“看到”只是一个普通的函数调用。在下面的示例中,我创建了“并行”装饰器 - 只需将它放在任何函数之前,它就会在调用时自动在单独的进程中运行:

from multiprocessing import Process
from functools import partial

from time import sleep

def parallel(func):
    def parallel_func(*args, **kw):
        p = Process(target=func, args=args, kwargs=kw)
        p.start()
    return parallel_func

@parallel
def timed_print(x=0):
    for y in range(x, x + 10):
        print y
        sleep(0.2)



def example():
    timed_print(100)
    sleep(0.1)
    timed_print(200)
    for z in range(10):
        print z
        sleep(0.2)


if __name__ == "__main__":
    example()

When running this snippet, one gets:

运行此代码段时,会得到:

[gwidion@caylus Documents]$ python parallel.py 
100
0
200
101
1
201
102
2
202
103
3
203
104
4
204
105
5
205
106
6
206
107
7
207
108
8
208
109
9
209
[gwidion@caylus Documents]$ 

回答by monkut

Using multiprocessingin python:

在python中使用多处理

from multiprocessing import Process

def b():
    # long process

p = Process(target=b) 
p.start()

回答by Ted Hopp

In Java, there's a standard idiom: create a thread and run it:

在 Java 中,有一个标准的习惯用法:创建一个线程并运行它:

new Thread() {
    @Override
    public void run() {
        callMyFunction();
    }
}.start();

Or you can create a Runnable and pass it to the thread:

或者您可以创建一个 Runnable 并将其传递给线程:

Runnable caller = new Runnable() {
    @Override
    public void run() {
        callMyFunction();
    }
}

new Thread(caller).start();

回答by Flavio

You'd better start with an ExecutorServiceinstead of going directly with raw threads. It provides pooling, completion detection, and there are subclasses which also have some scheduling. For instance:

您最好从ExecutorService开始,而不是直接使用原始线程。它提供池化、完成检测,并且有一些子类也有一些调度。例如:

...
// Create a simple instance with a single thread in the pool
ExecutorService executor = Executors.newFixedThreadPool(1); 
...
Future<Integer> future = executor.submit(new Callable<Integer>() {
    @Override
    public Integer call() {
        return YourFunction();
    }
});
...

// To wait for YourFunction() to finish, and get the result:
Integer result = future.get();

You can submit as many asynchronous tasks to the ExecutorService as you like; they will be executed in parallel, or sequentially, depending on the implementation you choose, on the number of threads in the backing thread pool, etc.

您可以根据需要向 ExecutorService 提交任意数量的异步任务;它们将并行或顺序执行,具体取决于您选择的实现、支持线程池中的线程数等。

回答by codeslord

Since jsbueno's answer will not work in all windows systems, as os.fork will not work efficiently there due to restrictions in the os, you will have to use multithreading there to achieve the same effect.

由于 jsbueno 的答案不适用于所有 Windows 系统,因为 os.fork 由于 os 中的限制而无法在那里有效地工作,因此您必须在那里使用多线程来实现相同的效果。

Please find the same code from jsbueno's answer with multithreading instead of multiprocessing (Python 3 version)

请从 jsbueno 的答案中找到相同的代码,使用多线程而不是多处理(Python 3 版本)

from threading import Thread

from time import sleep

def thread_parallel(func):
    def parallel_func(*args, **kw):
        p = Thread(target=func, args=args, kwargs=kw)
        p.daemon = True
        p.start()
    return parallel_func

@thread_parallel
def timed_print(x=0):
    for y in range(x, x + 10):
        print(y)
        sleep(0.2)


def example():
    timed_print(100)
    sleep(0.1)
    timed_print(200)
    for z in range(10):
        print(z)
        sleep(0.2)


if __name__ == "__main__":
    example()