一、并发与并行
从宏观上讲,并发与并行都是同时发起多个请求来执行任务,但是并发只是几个程序处在操作系统的同一个处理机上,通过时间分片的方式来达到几个程序同时运行,只是时间片时间非常的短暂,让人无法感知它在任意一个时间点是单独运行的状态。然而并行就不一样了,并行是同一个时间点,几个程序是同时运行的,并不需要时间片。
二、大数据的MapReduce思想
MapReduce是一种编程模型,主要用来处理大数据集合,它最早是由谷歌公司提出的,初衷是为了解决搜索引擎中大规模网页的数据的并行化处理。刚接触这个概念可能有点陌生,网上也有N多种解说,我不一一照叙,按我的理解来简单概括下它的概要,map主要是用来把一个集合做拆分处理,分解成项后,这个过程简称映射,也叫map;拆分成项后然后进行数据计算,这个过程就是数据的计算处理;计算后,做reduce规约处理,这个举个例子,类似于excel表中的汇总函数的sum和average,主要是对数据计算的结果进行归并最后汇总出最终的结果。MapReduce通过映射拆分项使得一个大的数据集合可以分割为一个个比较小的数据集合,通过数据处理后进行规约,又可以得到最终的计算结果,运用在大规模的网页处理和日志分析,利用分布式的节点处理,可以大大提高处理大数据的效率。
三、Fork/Join框架
Fork/Join是java 7提供的一个可用来并行执行任务的框架,跟MapReduce的思想类型,它是把大任务拆分成小任务,最终汇总小任务结果得到大任务的结果。由于是并行,它并不需要跟其它的任务去抢占时间片,每个任务都会单独的在队列里面执行并完成任务,相比多线程,理论上会更高效一点。
四、实战例子
下面举个简单的例子来比较下普通处理方法,多线程处理方法和ForkJoin的处理方法,这个计算任务是从1加到10亿。下面讲解一下各自的处理思路。
普通处理方法就是利用for循环从1一直加到10亿,然后直接得出结果。
多线程的处理方法是对1到10亿进行分页,按1万大小来分页,每1万个分页就开启一个线程来处理,10亿个拆分后将会1万个线程来计算。
ForkJoin的处理方法是按1万个为维度进行map拆分计算任务,将会拆分出1万个子任务来计算,计算完成后会对1万个计算任务的结果进行reduce操作,最后得到结果。
现在展示代码吧。
1.普通方法:
2.多线程方法:
3.ForkJoin方法
(1) 先定义任务
(2) 再调用任务执行
(3) 最后在main函数里面分别调用
(4) 最后执行的结果
最后得出的结果当然都是500000000500000000,耗时比对的话,是普通方法最快,多线程其次,ForkJoin耗时最多,这又是为什么呢,这是因为加法本身是一种很简单的运算,对于现在的处理器来说计算来说非常快,但是从计算机的资源消耗对比,普通方法消耗最少,所以最快,而多线程则要切分出10000个线程来处理,任务切分派发的过程消耗了大量的资源,而最消耗资源的是ForkJoin,因为它要切分1万个计算任务出来,每个计算任务都新建了一个对象,对java虚拟机的堆内存带来了很大的消耗,所以最慢。
当然测试的结果与实际应用是不一样的,当处理的大数据是在TB和PB级别的时候,资源消耗的实际几乎可以忽略不计,而这个时候最快的应该是ForkJoin,其次是多线程,最慢的是普通处理方法。