Java回调以及如何获取线程的执行结果

Python09

Java回调以及如何获取线程的执行结果,第1张

软件模块之间存在调用的接口,从调用方式来看,有同步调用、回调、异步调用这三种方式:

同步调用是是一种阻塞式调用,调用方要等待被调用方执行完毕返回后才能获取调用的执行结果,是一种单向调用。

回调是一种双向调用,调用方在执行被调用方后,被调用方会调用被调用方的接口

异步调用是一种类似消息或者事件的机制,接口在收到某个消息或发生某事件时,会主动通知客户方,通常使用回调来实现异步调用。

Java回调的必须要素: 

1.雇主类必须有可以被观察者调用的方法A; 

2.观察者必须持有可以调用A的对象的引用。

在实际工作中,我们通常将方法A以interface或者内部类的形式来实现,然后把包含有A的类的对象引用传递到观察者中。

Java中的线程的返回值是void,并且是一个异步执行流,所以我们没有直接的方法来获取线程执行后的结果,即不能直接知道线程何时结束,以及合适去获取线程执行任务后的结果。由于回调的存在,我们可以在线程中以回调的方式通知线程的调用者线程的结束时间,并可以将任务的结果通过回调回送到调用者中。

java中提供了Future<V>接口和实现了Future接口的FutureTask<V>类来将线程执行之后的结果返回(通过get()方法)。

1.Future<V>接口

Runnable接口执行任务是不返回任何值的,Runnable的run()方法的执行结果是void,而Future接口的call方法是有返回结果的,这是Runnable跟Future的区别之一,它们的另一个不同之处就是实现了Runnable接口的任务执行是调用ExecutorService的execute(Runnable task)方法,而实现了Future接口的任务是调用ExecutorService的submit(Future task)方法。调用Future的get()方法就能直接得到任务的返回值,该方法会一直阻塞直到任务的结果出来为止,我们可以调用Future的isDone()方法来判断该任务的结果是否准备就绪。

[java] view plain copy

import java.util.concurrent.Callable

import java.util.concurrent.ExecutionException

import java.util.concurrent.ExecutorService

import java.util.concurrent.Executors

import java.util.concurrent.Future

public class TestFuture {

public static void main(String[] args) throws InterruptedException, ExecutionException {

ExecutorService executor = Executors.newCachedThreadPool()

Future result1 = executor.submit(new Callable() {

@Override

public Integer call() throws Exception {

int sum = 0

for (int i = 0i <10i++) {

sum += i

}

return sum

}

})

Future result2 = executor.submit(new Callable() {

@Override

public Integer call() throws Exception {

int sum = 0

for (int i = 10i <100i++) {

sum += i

}

return sum

}

})

executor.shutdown()

System.out.println(result1.get() + result2.get())

}

}

2.FutureTask类

FutureTask实现了Future接口,将一个Callable实例作为参数传给它,就能创建一个FutureTask实例,然后用ExecutorService的submit方法来执行这个实例。最后同样是用get方法获取线程执行后的结果。

[plain] view plain copy

import java.util.concurrent.Callable

import java.util.concurrent.ExecutionException

import java.util.concurrent.ExecutorService

import java.util.concurrent.Executors

import java.util.concurrent.FutureTask

public class TestFutureTask {

public static void main(String[] args) throws InterruptedException, ExecutionException {

ExecutorService executor = Executors.newCachedThreadPool()

Callable task = new Callable() {

@Override

public String call() throws Exception {

return "结果"

}

}

FutureTask ft = new FutureTask(task)

executor.submit(ft)

System.out.println(ft.get())

executor.shutdown()

}

}empty

写个方法:

public Thread getThreadByName(String threadName) {

for (Thread t : Thread.getAllStackTraces().keySet()) {

if (t.getName().equals(threadName)) return t

}

return null

}