多线程之串行实现

比如有这么个需求:有线程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方法。这几者之间的关系大家结合上面例子,稍微思考一下,应该就很清晰了。


希望本文能够帮到大家!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容