Android技术知识Android开发经验谈Android开发

多线程之串行实现

2017-11-16  本文已影响792人  CaptainJno

比如有这么个需求:有线程A、B。A线程是搬砖,B线程是盖房,B必须在A完成后执行。怎么办?

一、用Thread的join方法

join中参数为启动banzhuanThread的线程等待banzhuanThread执行的时间,时间到达后,代码接着往下执行。参数缺省时会一直等待时间无穷,直到执行完成。

如果搬砖的人半路不干了(线程A未按理想情况完成),砖没搬完,就不能开始盖房,此时join方法就不适合这种场景了。接下来就需要用到Future/FutureTask,它们能告诉你搬砖是正常完成还是其他特殊情况。

二、用Future或FutureTask:

先简单对比一下Future和FutureTask:

相同点:

1)、Future和FutureTask都可以通过调用get(),获得Callable中返回的结果,并且该方法是线程阻塞的;

不同点:

1)、Future是个接口,用来展现异步执行的结果;

2)、FutureTask是个类,实现了RunnableFuture接口(RunnableFuture又同时继承了Runnable和Future接口);不难看出,FutureTask比Future多了个Runnable。这也就意味着在使用上存在一些的不同。

再来看两个简单的例子:

首先我们自定义一个BanzhuanCallable实现Callable接口。Callable接口类似Runnable,两者都是用于多线程。最重要区别是:Runnanble不返回线程执行结果并且也无法抛出受检异常。而,Callabel却可以。

搬砖Callable

1、用FutureTask实现:

由于FutureTask实现了Runnable接口,所以可以直接传参给Thread构造方法,并调用start执行。

用FutureTask实现

2、用Future实现:

Future实现需用到线程池(这里为了方便直接用的Executors.newCachedThreadPool(),大家可以自行单例化一下)。

用Future实现

当然,例子1中new Thread也可以换成线程池,调用execute/submit方法。


补充一个知识点:

线程池的submit传参可以是Runnable,也可以是Callable。最后都会转换成RunnableFuture(FutureTask就是实现的这个接口)。

java线程池源码部分 java线程池源码部分

上面讲了这么多,提到Callable、Runnable、Future、FutureTask、线程池submit方法。这几者之间的关系大家结合上面例子,稍微思考一下,应该就很清晰了。


希望本文能够帮到大家!

上一篇下一篇

猜你喜欢

热点阅读