java 异步处理接口_java中原来是这样获取异步处理结果!!

导读

有不少童鞋问我多线程的处理结果要如何返回给调用者呢?今天博主就给大家介绍一下如何采用Future模式,来获取线程的处理结果。

Future模式

Java 1.5开始,提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。

Future接口可以构建异步应用,是多线程开发中常见的设计模式。

当我们需要调用一个函数方法时。如果这个函数执行很慢,那么我们就要进行等待。但有时候,我们可能并不急着要结果。

因此,我们可以让被调用者立即返回,让他在后台慢慢处理这个请求。对于调用者来说,则可以先处理一些其他任务,在真正需要数据的场合再去尝试获取需要的数据。

java 异步处理接口_java中原来是这样获取异步处理结果!!_第1张图片

1、Callable与Runnable

java.lang.Runnable是一个接口,在它里面只声明了一个run()方法,run返回值是void,任务执行完毕后无法返回任何结果

1

2

3public interface Runnable {

public abstract void run();

}

Callable位于java.util.concurrent包下,它也是一个接口,在它里面也只声明了一个方法叫做call(),这是一个泛型接口,call()函数返回的类型就是传递进来的V类型

1

2

3public interface Callable {

V call() throws Exception;

}

2.Future + Callable

Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果

1

2

3

4

5

6

7

8public interface Future {

boolean cancel(boolean mayInterruptIfRunning);

boolean isCancelled();

boolean isDone();

V get() throws InterruptedException, ExecutionException;

V get(long timeout, TimeUnit unit)

throws InterruptedException, ExecutionException, TimeoutException;

}

怎么使用Future和Callable呢?一般情况下是配合ExecutorService来使用的,在ExecutorService接口中声明了若干个submit方法的重载版本

1

2

3 Future submit(Callable task);

Future submit(Runnable task, T result);

Future> submit(Runnable task);

Future+Callable,使用示例如下(采用第一个方法):

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30import java.util.Random;

import java.util.concurrent.*;

/**

* @program: callable

* @description: Test

* @author: Mr.Wang

* @create: 2018-08-12 11:37

**/

public class MyTest {

public static void main(String[] args) {

ExecutorService executor = Executors.newCachedThreadPool();

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

public Integer call() throws Exception {

return new Random().nextInt();

}

});

executor.shutdown();

try {

System.out.println("result:" + result.get());

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

}

}

结果:

result:297483790

其它方式:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39import java.util.Random;

import java.util.concurrent.*;

/**

* @program: callable

* @description: testfuture

* @author: Mr.Wang

* @create: 2018-08-12 12:11

**/

public class Testfuture {

public static void main(String[] args){

//第一种方式

FutureTask task = new FutureTask(new Callable() {

@Override

public Integer call() throws Exception {

return new Random().nextInt();

}

});

new Thread(task).start();

//第二种方方式

// ExecutorService executor = Executors.newSingleThreadExecutor();

// FutureTask task = new FutureTask(new Callable() {

// @Override

// public Integer call() throws Exception {

// return new Random().nextInt();

// }

// });

// executor.submit(task);

try {

System.out.println("result: "+task.get());

} catch (InterruptedException e) {

e.printStackTrace();

} catch (ExecutionException e) {

e.printStackTrace();

}

}

}

结果:

result:-358490809

3、Future 接口的局限性

了解了Future的使用,这里就要谈谈Future的局限性。Future很难直接表述多个Future 结果之间的依赖性,开发中,我们经常需要达成以下目的:

将两个异步计算合并为一个(这两个异步计算之间相互独立,同时第二个又依赖于第一个的结果)

等待 Future 集合中的所有任务都完成。

仅等待 Future 集合中最快结束的任务完成,并返回它的结果。

总结

因为Future本身有一些局限性,所以还是不能满足大部分应用场景,下一节我将给大家介绍更高级的用法:CompletableFuture。

更多内容敬请关注:“林老师带你学编程”

你可能感兴趣的:(java,异步处理接口)