多线程之串行实现

作者: CaptainJno | 来源:发表于2017-11-16 19:51 被阅读792次

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


    希望本文能够帮到大家!

    相关文章

      网友评论

        本文标题:多线程之串行实现

        本文链接:https://www.haomeiwen.com/subject/jyqrvxtx.html