Java并行程序设计模式小结

转自:http://www.cnblogs.com/panfeng412/p/java-program-tuning-reading-notes-of-concurrent-program-design-pattern.html

这里总结几种常用的并行程序设计方法,其中部分文字源自《Java程序性能优化》一书中,还有部分文字属于个人总结,如有不对,请大家指出讨论。

Future模式

一句话,将客户端请求的处理过程从同步改为异步,以便将客户端解放出来,在服务端程序处理期间可以去干点其他事情,最后再来取请求的结果。

好处在于整个调用过程中不需要等待,可以充分利用所有的时间片段,提高系统的响应速度。

JDK中已经内置实现了FutureTask,使用起来非常方便,同时还可以取消Future任务,或者设置Future任务的超时时间。

1)实现一个Callable接口,实现服务端的具体的业务逻辑计算:

public class RealData implements Callable<String> {
    public String call() throws Exception {...}
}

2)定义FutureTask,提交执行,获取返回结果:

// 1. create future task
FutureTask<String> future = new FutureTask<String>(new RealData("aaa"));
// 2. submit future task
ExecutorService exexutor = Executors.newFixedThreadPool(1);
exector.submit(future);
// 3. do other thing
......
// 4. get result, waiting util call method finished
System.out.println("Result:" + future.get());

Master-Worker模式

由两类线程实现:Master线程负责接收和分发任务(将任务拆成一个个的子任务);Worker线程负责处理子任务,每个Worker线程只处理部分任务,所有Worker线程共同完成所有任务的处理。

好处在于能够将一个大的任务拆分成若干个小的任务,从而交给不同的Worker并行的进行处理,进而提高系统的吞吐量。另外,Client端一旦提交任务后,Master线程完成任务的接收和分发后立即返回,因此对客户端来说,整个过程也是异步进行的。

一般的实现思路如下:

1)Master中首先需要维护一个队列Queue,用于接收任务,同时维护一个所有Worker线程的threadMap,以及每个子任务对应的处理结果集resultMap,这里由于涉及到多线程同时访问resultMap,因此一般使用JDK中的ConcurrentHashMap实现;

2)Worker线程实现Runnable或继承Thread,通过Master中的Queue获取拆分后的子任务,并进行业务处理,并将处理结果设置到resultMap中以便Master获取到;

3)Main入口函数则负责客户端请求的提交(需要先进程拆解),以及通过Master获取各个Worker的结果后进行合并,最后返回给客户端完成处理过程。

Guarded Suspension模式

所谓“保护暂停”模式,核心思想在于仅当服务进程准备好时,才提供服务。

好处在于既能保证所有的客户端请求均不丢失,同时也避免了服务器由于同时处理太多的请求而崩溃的现象,有效降低系统的瞬时负载,有助于系统稳定性。

其实这种通过中间加一层Queue做缓冲的模式在工作中用的很多,类似“ClientThread -> Request Queue -> ServerThread”的情况比比皆是,只不过可能实际中我们往往会结合其他方法一起使用,例如:

1)将ClientThread和ServerThread均为多个,则变为经典的“生产者-消费者”模式;

2)如果将ServerThread拆为1个Master和多个Worker,则又是上面提到的“Master-Worker”模式;

3)如果处理的请求需要返回结果,那么又需要和FutureTask结合起来使用(即:客户端的请求中需要带上FutureData,并在ServerThread中为FutureData设置上RealData)。

不变模式

并发多线程程序中,当多线程对同一个对象进行读写操作时,为了确保对象数据的一致性和准确性,必须进行同步操作,而这正是对系统性能损失严重的地方。因此,为了提高并发并发程序的性能,我们可以创建一种不可改变的对象,使用过程中保持不变性。这就是所谓“不变”模式。Java中这种模式用的很广,如String、Boolean、Short、Integer、Long、Byte等。

好处在于通过回避问题而不是解决问题的态度来处理多线程并发访问控制,但缺点是只适用于对象创建后内部状态和数据不可发生变化的情况。

Java中不变模式的实现很简单,按照OO的思想,只需要满足以下几点即可:

1)将对象的所有属性设为private final的;

2)通过final修饰class确保类不可被继承;

3)去掉对象中的所有settXX方法;

4)有包含所有属性的构造函数用于创建对象。

生产者-消费者模式

生产者线程向内存缓冲区提交任务,消费者线程从内存缓冲区获取任务并进行处理。

好处在于将生产者线程和消费者线程进行解耦,优化系统整体结构,缓解性能瓶颈对系统性能的影响。

Java中,一般来说使用LinkedBlockingQueue作为上面说的“内存缓冲区”,它是阻塞型BlockingQueue的一种使用Link List的实现,它对头和尾采用两把不同的锁,与ArrayBlockingQueue相比提高了吞吐量,适合于实现“生产者-消费者”模式。实现的大致思路如下:

1)创建Producer类,实现run方法用于提交任务;

2)创建Consumer类,实现run方法用于处理任务;

3)Main函数中建立缓冲区,若干个生产者,若干个消费者,创建线程池并开始使这些线程工作起来。

时间: 2024-08-09 19:51:36

Java并行程序设计模式小结的相关文章

JAVA并行程序基础

JAVA并行程序基础 一.有关线程你必须知道的事 进程与线程 在等待面向线程设计的计算机结构中,进程是线程的容器.我们都知道,程序是对于指令.数据及其组织形式的描述,而进程是程序的实体. 线程是轻量级的进程,是程序执行的最小单位.(PS:使用多线程去进行并发程序的设计,是因为线程间的调度和切换成本远小于进程) 线程的状态(Thread的State类): NEW–刚刚创建的线程,需要调用start()方法来执行线程: RUNNABLE–线程处于执行状态: BLOCKED–线程遇到synchroni

【MPI学习6】MPI并行程序设计模式:具有不连续数据发送的MPI程序设计

基于都志辉老师<MPI并行程序设计模式>第14章内容. 前面接触到的MPI发送的数据类型都是连续型的数据.非连续类型的数据,MPI也可以发送,但是需要预先处理,大概有两类方法: (1)用户自定义新的数据类型,又称派生类型(类似定义结构体类型,但是比结构体复杂,需要考虑<类型,偏移量>两方面的内容) (2)数据的打包和解包(将不连续的数据给压缩打包到连续的区域,然后再发送:接受到打包数据后,先解包再使用) 这样做的好处,我猜一个是可以有效减少通信的次数,提高程序效率:另一方面可以减轻

关于Java并行程序

因为某种需要,要编写类似于C++OpenMP的Java多线程程序.但是,由于对Java编程不熟悉.对于Java多线程编程,有大概4-5中实现方法.我采用的是Executor框架和线程池. 具体内容见链接 http://blog.csdn.net/ns_code/article/details/17465497

【MPI学习2】MPI并行程序设计模式:对等模式 &amp; 主从模式

这里的内容主要是都志辉老师<高性能计算之并行编程技术——MPI并行程序设计> 书上有一些代码是FORTAN的,我在学习的过程中,将其都转换成C的代码,便于统一记录. 这章内容分为两个部分:MPI对等模式程序例子 & MPI主从模式程序例子 1. 对等模式MPI程序设计 1.1 问题背景 这部分以Jacobi迭代为具体问题,列举了三个求解Jacobi迭代问题的MPI对等模式程序. 这里需要阐明一下,书上的Jacobi迭代具体的背景可以参考这个内容:http://www.mcs.anl.g

Java并行程序基础总结

1-1 线程概念 1. 同步(Synchronous)和异步(Asynchronous) 2. 并发和并行 3. 临界区 4. 阻塞与非阻塞 5. 死锁.饥饿.活锁 6. 并发级别:阻塞.无饥饿.无阻碍.无锁.无等待 7. 并发的两个重要定律:Amdahl.Gustafson定律 2-1.线程的基本操作 2.1 创建线程 创建线程的第一种方式:继承Thread类. 步骤: 1,定义类继承Thread. 2,复写Thread类中的run方法. 目的:将自定义代码存储在run方法.让线程运行. 3,

用java理解程序逻辑小结

1.Java常见的注释有哪些,语法是怎样的? 1.单行注释用//表示,编译器看到//会忽略该行//后的所文本 2.多行注释/* */表示,编译器看到/*时会搜索接下来的*/,忽略掉/* */之间的文本. 3.文档注释用/** */表示,是java特有的注释,其中注释内容可以被JDK提供的工具 javadoc 所解析,生成一套以网页文件形式体现的该程序的说明文档. 单行注释. // 注释的内容 多行注释. /* 注释的内容 */ 文档注释. /** 注释的内容 */ 2.java常见的运算符都有哪

【MPI学习3】MPI并行程序设计模式:不同通信模式MPI并行程序的设计

学习了MPI四种通信模式 及其函数用法: (1)标准通信模式:MPI_SEND (2)缓存通信模式:MPI_BSEND (3)同步通信模式:MPI_SSEND (4)就绪通信模式:MPI_RSEND 四种通信模式的区别都在消息发送端,而消息接收端的操作都是MPI_RECV. 1.标准通信模式 原理图如下 标准通信模式由MPI决定是否用缓存. 如果MPI决定缓存将要发出的数据:发送操作不管接受操作是否执行,都可以进行:而且缓存结束后发送操作就可以返回,不需要等待接受操作收到数据 如果MPI决定不缓

Java 下各种设计模式小结

策略模式--定义算法族,分别封装起来,让它们之间能够互相替换,此模式让算法的变化独立于使用算法的客户. 策略模式是说,针对一种计算,定义一系列的算法,由用户决定详细使用哪一个算法完毕计算. 比方,提供一个计算银行存款利率的接口,对于不同的存款方式(活期.一年定期.两年定期),提供不同的算法实现类,由用户决定使用哪种存款方式来计算利率.假设银行计算利率的算法发生了变化(如又添加了三年定期.五年定期的算法),对于用户的使用不产生不论什么影响,由于用户使用的是统一的计算接口,也符合了针对接口编程,不针

《Java程序性能优化》学习笔记 Ⅲ 并行程序优化

第四章 并行程序优化4.1 并行程序设计模式4.2 JDK多任务执行框架4.3 JDK并发数据结构4.4 并发控制方法4.5 锁的性能和优化4.6 无锁的并行计算 1.非阻塞同步避免了基于锁的同步的缺陷,无锁算法没有锁竞争带来的系统开销,也没有线程间频繁调度带来的开销.CAS算法:包含3个参数CAS(v,e,n).V表示要更新的变量,E表示预期值,N表示新值2.JDK的java.util.concurrent.atomic包下,有一组使用无锁算法实现的原子操作类,如AtomicInteger/A