Java高并发程序设计(七)—— 并行设计模式
一、什么是设计模式
1. 在软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。这个术语是由埃里希·伽马(Erich Gamma)等人在1990年代从建筑设计领域引入到计算机科学的。
2. Richard Helm,Ralph Johnson,John Vlissides(Gof)
3. 《设计模式:可服用面向对象软件的基础》收录23种模式
4. 架构模式
MVC
分层
5. 设计模式
提炼系统中的组件
6. 代码模式(成例 Idiom)
低层次,与编码直接相关
如DCL
二、单例模式
1. 单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个全局对象,这样有利于我们协调系统整体的行为。
2. 比如:全局信息配置
3. 最简单实现
缺点:何时产生实例,不好控制
如下例:
4. 改进:同步方法,延迟加载
缺点:synchronized影响性能。
5. 改进:延迟加载,静态内部类
三、不变模式
1. 一个类创建后,它的内部状态在整个生命期间都不会发生变化时,就是不变类。
不变类为什么对多线程来讲非常重要?原因是:不变模式不会被修改,换句话说,它是一个只读的应用对象,对于一个只读对象来说,它不需要同步的。而多线程之间,最重要的就是进行各种各样的同步,同步是非常消耗资源的,因此不变模式直接丢到这个并行的系统中,它其实可以很好的工作,并且可以提供非常好的性能。
2. 不变模式不需要同步
所以,我们在实现一些类,在多线程中被频繁的访问,可以把它设计为不变模式。
3. 实现代码
特点:
类被声明为final,确保无子类。
所有字段都必须私有,符合Javabean规范。注意没有set方法,创建后不会改变。
所有字段必须都被声明为final,不允许二次赋值。在对象被创建时,构造函数中赋值。
4. 不变模式案例
四、Future模式
1. Future模式是一种使用非常广泛的模式,它甚至可以继承在JDK的开发包当中。
Future模式的核心思想就是异步调用,比方说,客户端向服务器端调用一个的函数,服务端可能需要做某些事情,把调用满足,可能构造某一个数据,可是这个过程很慢,要很久,做完后把数据返回给服务端,再返回给客户端,然后客户端再去做别的事情。如果是Future模式,客户端向服务端发送请求,这时服务端与之前花了好久才返回的做法不同,服务端立即返回,将来的某一个时间才拿到数据。一段耗时程序的返回,不需要立即去得到它。
2. 简单实现
有一个接口Data,就是要拿到的数据。接着有一个Future Data和一个RealData,实现了Data接口。Future Data不是一个真实的数据,但是它跟真实的数据共享一个接口,因此在使用过程中,使用接口Data接口,来代替数据。被调用者给一个Data就可以,不需要知道是Real Data还是Future Data,Real Data的构建可能很慢,可能等不及,所有拿到的真实的实例是Future Data。接着在未来的某一个阶段,通过FutureData拿到RealData,两者的关系是FutureData聚合一个RealData,如果RealData被射入进去,则FutureData就知道了,数据已经组装完毕。ReadData很慢,所以需要装配起来。在未来某个时间段,在RealData已经装配完成之后,需要装载到FutureData之后。
3. 示例代码
Future模式就是把一个同步的阻塞的调用,变成一个异步的调用
4. JDK对Future模式的支持
Future模式是很常见的,所以JDK也拿进来,做了一个包装和实现。
五、生产者消费者模式
1. 生产者-消费者模式是一个经典的多线程设计模式。它为多线程间的协作提供了良好的解决方案。在生产者-消费者模式中,通常由两类线程,即若干个生产者线程和若干个消费者线程。生产者线程负责提交用户请求,消费者线程则负责具体处理生产者提交的任务。生产者和消费者之间则通过共享内存缓冲区进行通信。
2. 角色
3. 结构图
4. 简要代码