软件模块之间存在调用的接口,从调用方式来看,有同步调用、回调、异步调用这三种方式:
同步调用是是一种阻塞式调用,调用方要等待被调用方执行完毕返回后才能获取调用的执行结果,是一种单向调用。
回调是一种双向调用,调用方在执行被调用方后,被调用方会调用被调用方的接口;
异步调用是一种类似消息或者事件的机制,接口在收到某个消息或发生某事件时,会主动通知客户方,通常使用回调来实现异步调用。
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
}