`

当线程有了返回值——多线程设计之Future设计模式

阅读更多

先由一个例子引入什么是Future Pattern。

【例子】我去蛋糕店取蛋糕,下订单后,店员请我"请在天黑后再来店里取货",并给我一张提货单。在店员做蛋糕的时候,我可以陪MM逛街,看电影等,而不需要在蛋糕店外等候。黄昏后,我拿着这张提货单到蛋糕店来取货。店员说了声"先生,你的蛋糕好了",并把蛋糕给了我。

上面的例子就是Future Pattern的一个直观的使用例子。

  1. 假设有一个执行起来要花很久的方法(如做蛋糕),我们不需要等待结果完全出来了(蛋糕做好),而是获取一张替代的"提货单"。获取提货单不需要太长的时间,这个提货单就是Future参与者
  2. 获取Future参与者的线程,会在事后再去执行结果,就好像拿着提货单取蛋糕一样。如果已经有执行结果了,就马上拿到数据。如果还没有,则继续等待到执行结果完全出来为止。

上面就是一此完整的Future Pattern的运行模式。

下面提供一段范例程序。

首先介绍一下范例程序包含的一些类和接口:

  1. Main 说明:对Host送出请求,获取数据的类。
  2. Host 说明:对请求返回FutureData的类。
  3. Data 说明:表达数据访问方式的接口,FurureData与RealData都实现了这个接口。
  4. FurureData说明:RealData的提货单类,而RealData实例则有其他线程建立。
  5. RealData说明:表达实际数据的类,执行构造器要花一定的时间。

运行结果如下:

对结果的分析:

可以看到最开始Main线程开始后,三个请求线程,开始后马上就结束了。这一过程就好像有三个人去蛋糕店订蛋糕,立刻就拿到了提货单。这一过程体现在输出结果的1到7行。

这之后,三个人分别忙自己的事情去了,假设时间刚好为一下午(反映在程序中就是Main线程sleep的那2000毫秒),这期间蛋糕店的师傅也没闲着,加紧做蛋糕,最先做谁的蛋糕也完全随机,结果反映就是先做C,在A,最后是B。也就是输出结果的8到14行。

三个玩够了,肚子饿了。想起来蛋糕店还有蛋糕呢,于是去取蛋糕。这个时候蛋糕已经做完了,三个人顺利取走蛋糕回家。也就是结果的最后15到19行。

从程序来看,Future Pattern有几个必要的参与者。

  • Client(委托人)参与者,反映在程序中就是想Host发送请求的参与者,并得到VirtualData参与者,作为这个请求的结果(返回值),在实例程序中就是Main类。
  • Host(处理人)参与者,建立新的线程,开始建立RealData参与者,另一方面会对Client参与者,以(VirtualData参与者的形式)返回Future参与者。新的线程建立出来RealData后,会对Future参与者设置RealData参与者。示例Host就是Host。
  • VirtualData(虚拟数据)参与者,用来统一代表Future参与者和RealData参与者。在示例中就是Data接口。
  • RealData(实际数据)参与者,表示实际的数据,建立需要花一些时间,示例中RealData就是RealData。
  • Future(期货)参与者,Future是Host参与者传递给Client参与者,当做是RealData参与者"提货单"使用的参与者。Future参与者相对于Client参与者而言,可以进行VirtualData参与者的行为。

扩展思考:

1.吞吐量由提高吗?

对于我们的程序,对于单CPU的系统,CPU处理的总时间是一样的,因为计算机宏观并行,微观串行所决定。然而,如果加上I/O处理,如对硬盘的访问,大部分时间CPU只是等待工作结束而已,对于CPU,这部分时间是空闲时间,若能把空闲时间给其他的线程使用,那么相当于也提高了计算机的吞吐量。

2.响应性的提高?

对于此种模式,你不必等待某个工作的完成,你可以串行的干一些其他的工作。

3.实现异步?

使用此模式,通过"稍后在设置真正的处理结果",做到异步方法调用的返回值。

4.分离"准备返回值"和"使用返回值"

建立RealData的操作就是"准备方法的返回值",而调用getContent方法则是为了"使用方法的返回值"。如此,将调用方法的一系列动作,像慢动作播放一样逐一拆解,就可以把多线程当做道具来使用了。

Future设计模式是很有意思的一个模式,今天学习时很是喜欢,摘录一些段落加上自己的理解记录下来,与大家分享。

大部分摘自《Java多线程设计模式详解》一书。

分享到:
评论

相关推荐

    java多线程设计模式详解

    Java多线程设计模式是Java开发中不可或缺的一部分,它涉及到并发编程的核心理论和技术。这份PDF文档,"java多线程设计模式详解",提供了一种深入理解如何在Java环境中高效利用多线程并保证程序稳定性的途径。下面,...

    java多线程高级设计模式详解

    Java多线程高级设计模式详解 在Java编程中,多线程是不可或缺的一部分,它能够充分利用多核处理器的计算能力,提高程序的并发性能。本文将深入探讨Java多线程中的高级设计模式,帮助开发者更好地理解和应用这些模式...

    图灵图书:图解JAVA多线程设计模式

    ### 图灵图书:图解JAVA多线程设计模式 #### 关键知识点概览 - **Java多线程基础** - 线程的概念与创建方式 - 线程的状态及其转换 - 线程生命周期 - **Java并发编程** - 同步机制(synchronized关键字) - ...

    Java多线程之异步Future机制的原理和实现共5页.p

    异步Future机制是Java多线程中用于提升效率和优化资源利用的一种设计模式,它允许我们在主线程中不等待子线程的执行结果,而是通过Future对象来获取子线程的计算结果。这种方式极大地提高了程序的响应速度,尤其是在...

    java多线程实现乒乓球双打

    总结来说,实现"java多线程实现乒乓球双打"需要对Java的线程API有深入的理解,包括线程的创建与启动、同步与通信机制、并发控制工具的使用以及设计模式的应用。通过这种方式,我们可以构建出一个生动有趣的模拟游戏...

    Java多线程编程总结

    - 生产者消费者模型是一种经典的多线程设计模式,用于解决线程间的协作问题。通常通过队列或缓冲区来实现。 #### 十、Java线程:并发协作-死锁 - 死锁是多个线程相互等待对方持有的锁而导致所有线程都无法继续执行...

    javase之多线程技术

    Java中的多线程技术是Java进阶学习的重要组成部分,它涉及到并发编程的理论与实践,旨在提高程序的执行效率和响应速度。以下是对多线程技术的详细解释: 1. **CPU调度算法原理** - **先来先服务(FCFS)**:按照...

    【Java】Callable创建线程用到的适配器模式(csdn)————程序.pdf

    在Java编程中,多线程是并发处理任务的关键机制,Callable接口和FutureTask类是Java提供的用于创建具有返回值的线程的重要工具。本文将详细解释Callable接口的使用、适配器模式在创建线程中的应用,以及FutureTask在...

    java多线程编程大总结

    7. 并发协作模型:生产者消费者模型、死锁等都是并发协作的经典问题,Java通过并发工具和设计模式提供了解决这些问题的方案。 8. Java并发包的新特性:包括线程池(ExecutorService)、有返回值的线程(Callable与...

    多线程执行完后主程序再执行(包括需要子线程返回结果)

    在编程领域,多线程是实现并发执行任务的重要方式,特别是在服务器端开发和高性能计算中。标题提到的“多线程执行完后主程序再执行(包括需要子线程返回结果)”是一个典型的多线程同步问题。在这个场景中,主程序会...

    java多线程序设计模式

    Java多线程程序设计模式是Java开发中的一种高级技术,它涉及到并发编程和系统性能优化。在现代计算机系统中,多核处理器的广泛使用使得多线程编程成为提高应用程序性能的关键。通过合理地利用多线程,我们可以实现...

    JAVA设计模式

    3. **观察者模式**:观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。在Java中,`java.util.Observable`和`java.util....

    多线程高频60道面试题

    【多线程】是计算机程序设计中的重要概念,特别是在Java这样的多线程支持的语言中,它使得程序能够利用多核CPU的优势,提高程序的运行效率。以下是对多线程相关知识点的详细阐述: 1. **多线程的作用**: - **发挥...

    java面试题_多线程(68题)

    53. **线程安全的事件驱动编程**:如发布订阅模式、观察者模式在多线程环境的应用。 54. **线程安全的单元测试**:如何设计和执行并发测试,验证代码的线程安全性。 55. **线程安全的并发编程最佳实践**:如避免...

    Java多线程编程经验谈

    关于编写多线程的经验分享,一种有效的方法是使用事件监听模式。例如,可以定义一个监听器接口,包含一个或多个同步方法,如`synData()`。线程之间通过注册监听器来进行通信。当需要同步数据时,线程调用监听器的...

    JAVA多线程面试59题(含答案)_.pdf

    - **使用ExecutorService、Callable、Future**:提供带返回值的多线程解决方案,Callable返回Future对象,用于获取线程执行结果。 4. **start()和run()的区别**: - **start()**启动线程,使得run()方法在独立的...

    Java线程技术精选

    这是一种经典的并发设计模式,其中生产者线程生成数据,消费者线程消耗数据。通过队列或其他共享数据结构,两个线程可以协同工作,而不会相互干扰。 5. **锁(下)**: 在Java中,锁是线程同步的重要工具,包括可...

    JAVA高质量并发详解,多线程并发深入讲解

    - **线程安全问题:** 如何避免共享资源访问冲突,确保多线程环境下的数据一致性。 - **核心API:** - **synchronized关键字:** 实现对象或代码块级别的独占锁,用于保证线程安全。 - **Lock接口:** 更灵活的...

    TheadPool 线程池源码 自动管理线程的创建和销毁

    5. **线程池的常见设计模式** - **固定大小线程池**:线程池大小固定,不随任务量动态调整。 - **可扩展线程池**:根据任务量动态调整线程数量。 - **单线程线程池**:只有一个工作线程,确保任务顺序执行。 - *...

    JUC线程锁框架

    在这个深度解析JUC线程锁框架的主题中,我们将探讨其核心组件、设计模式以及如何在实际应用中有效利用。 1. **原子变量(Atomic Variables)** JUC提供了一系列的原子变量类,如AtomicInteger、AtomicLong等,它们...

Global site tag (gtag.js) - Google Analytics