Huang

淘宝 柏林

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::
/**
* User: huangbaichuan
* Date: 11-8-21
* Time: 下午2:04
* To change this template use File | Settings | File Templates.
*/

import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.TimeUnit;

public class SortTask extends RecursiveAction {
final long[] array;
final int lo;
final int hi;
private int THRESHOLD = 0; //For demo only

public SortTask(long[] array) {
this.array = array;
this.lo = 0; //0
this.hi = array.length - 1;
}

public SortTask(long[] array, int lo, int hi) {
this.array = array;
this.lo = lo;
this.hi = hi;
}

protected void compute() {

//如果数据量比较少,就直接使用系统的排序方式
if (hi - lo < THRESHOLD)
sequentiallySort(array, lo, hi);
else {
int pivot = partition(array, lo, hi);
//把数组切分成两部分,然后在分别做排序
this.invokeAll(new SortTask(array,
pivot
+ 1, hi), new SortTask(array, lo, pivot - 1)) ;


}
}

private int partition(long[] array, int lo, int hi) {

long x = array[hi];
//-1
int i = lo - 1;
for (int j = lo; j < hi; j++) {
if (array[j] <= x) {
i
++;
swap(array, i, j);
}
}
swap(array, i
+ 1, hi);
return i + 1;
}

private void swap(long[] array, int i, int j) {
if (i != j) {
long temp = array[i];
array[i]
= array[j];
array[j]
= temp;
}
}

private static void sequentiallySort(long[] array, int lo, int hi) {
Arrays.sort(array, lo, hi
+ 1);
}

public static void main(String agrs[]) throws InterruptedException {

int length=1024;
Random r
=new Random();
long array[]=new long[length] ;

for(int i=0;i<length;i++){
array[i]
=r.nextInt(19087);
}

long t1=System.currentTimeMillis();

sequentiallySort(array,
0,array.length-1);

System.out.println(
"自然排序消耗时间为:" +( System.currentTimeMillis() - t1) );


//重新赋值

for(int i=0;i<length;i++){
array[i]
=r.nextInt(19087);
}
      long t2=System.currentTimeMillis();
        ForkJoinTask sort = new SortTask(array);
ForkJoinPool fjpool
= new ForkJoinPool();
fjpool.submit(sort);
fjpool.shutdown();
fjpool.awaitTermination(
30, TimeUnit.SECONDS);
System.out.print(
"fork/join并行消耗时间为:"+(System.currentTimeMillis()-t2));
}
}

  说明:

1:该程序不完全是个人写的代码,是http://www.ibm.com/developerworks/cn/java/j-lo-forkjoin/代码引用做了改造。做改造的原因是该文章中的方法是非正式版本的方法,正式版本中没有coInvoke函数。

2:该程序仅仅是作为一个简单的fork/join的示例,并不能表示出性能。在这个例子中性能反而不如直接使用系统的排序方法。,并且随着length的增加,fork/join的性能越来越差(切割的粒度,多线程切换的消耗)。

3:其他的一些信息,例如方法的意义,可以参考ibm的链接。

4:如果不能控制好任务切割的粒度以及平衡多线程的消耗,不如不使用。

5:fork/join没有太多新的思想。事实上,我们利用Future以及ExecutorService等多线程API,也能实现。

6:再次强调,慎用fork/join。

posted on 2011-08-21 14:57  Baichuan  阅读(3530)  评论(0)    收藏  举报