java fork/join框架下的歸并排序和快排

前言

  • Fork/Join框架是Java 7提供的一個(gè)用于并發(fā)執(zhí)行任務(wù)的框架危喉,其主要思想就是把大任務(wù)分割成若干的小任務(wù),最終匯總每個(gè)小任務(wù)結(jié)果后得到大任務(wù)結(jié)果的框架况凉。
  • 熟悉數(shù)據(jù)結(jié)構(gòu)的朋友可能立刻可以想到其中歸并排序也是也是一樣的思想舞肆,所以自然而然就想是否可以用fork/join框架實(shí)現(xiàn)并行(單CPU下為并發(fā))的歸并排序嚷往,基于這個(gè)考慮,就隨手寫了一個(gè)排序算法粘驰。

歸并排序

  • 下面是代碼
public class MergeSortTask extends RecursiveTask<Void>{
    //不需要返回值的task繼承RecursiveAction更好
    private int[] array;
    private int left;
    private int right;

    public static void main(String[] args) {
        int[] a = {4,2,1,4,7,5,3,8,2,7,1,78,89,6,5,4,8,5};
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        MergeSortTask task = new MergeSortTask(a, 0, a.length-1);
        Future<Void> result = forkJoinPool.submit(task);
        try {
            result.get();
            for (int n : a) {
                System.out.print(n + " ");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    public MergeSortTask(int[] array, int left, int right) {
        this.array = array;
        this.left = left;
        this.right = right;
    }

    @Override
    protected Void compute() {
        boolean isNeedSplit = right - left >= 1;
        if (isNeedSplit) {
            int mid = (left + right)/2;
            MergeSortTask mergeSortTask1 = new MergeSortTask(array, left, mid);
            MergeSortTask mergeSortTask2 = new MergeSortTask(array, mid+1, right);
            mergeSortTask1.fork();
            mergeSortTask2.fork();
            mergeSortTask1.join();
            mergeSortTask2.join();
            merge(array, left, mid, right);
        }else {
            int mid = (left+right)/2;
            merge(array, left, mid, right);
        }
        return null;
    }

    public static void merge(int a[], int left, int mid, int right) {
        int len = right - left + 1;
        int temp[] = new int[len];
        int i = left;
        int j = mid + 1;
        int index = 0;
        while(i<=mid && j <= right) {
            temp[index++] = a[i] <= a[j] ? a[i++] : a[j++];
        }
        while (i <= mid) {
            temp[index++] = a[i++];
        }
        while (j<=right) {
            temp[index++] = a[j++];
        }
        for (int k = 0; k<temp.length; k++) {
            a[left++] = temp[k];
        }
    }
}
  • 其實(shí)上面的這段代碼還是有很多問題的屡谐,比如用于沒有返回結(jié)果的任務(wù),繼承RecursiveAction更好蝌数,但是由于是第一次嘗試愕掏,就放著吧。

快速排序

  • 其實(shí)再想想顶伞,好像快排也可以用fork/join框架實(shí)現(xiàn)饵撑。
  • 下面是代碼
public class QuickSortTask extends RecursiveAction{

    private int[] array;
    private int left;
    private int right;

    public QuickSortTask(int[] array, int left, int right) {
        this.array = array;
        this.left = left;
        this.right = right;
    }

    @Override
    protected void compute() {
        int pivot = partition(array, left, right);
        QuickSortTask task1 = null;
        QuickSortTask task2 = null;
        if (pivot - left > 1) {
            task1 = new QuickSortTask(array, left, pivot-1);
            task1.fork();
        }
        if (right - pivot > 1) {
            task2 = new QuickSortTask(array, pivot+1, right);
            task2.fork();
        }
        if (task1 != null && !task1.isDone()) {
            task1.join();
        }
        if (task2 != null && !task2.isDone()) {
            task2.join();
        }
    }

    public static int partition(int[] a, int left, int right) {
        int pivot = a[left];
        while (left < right) {
            while (left < right && a[right] >= pivot) {
                right--;
            }
            swap(a, left, right);
            while (left < right && a[left] <= pivot) {
                left++;
            }
            swap(a, left, right);
        }
        return left;
    }

    public static void swap(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }

    public static void main(String[] args) {
        int[] a = {4,2,1,4,7,5,3,8,2,7,1,78,89,6,5,4,8,5};
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        QuickSortTask task = new QuickSortTask(a, 0, a.length-1);
        Future<Void> result = forkJoinPool.submit(task);
        try {
            result.get();
            for (int n : a) {
                System.out.print(n + " ");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末剑梳,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子肄梨,更是在濱河造成了極大的恐慌阻荒,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件众羡,死亡現(xiàn)場(chǎng)離奇詭異侨赡,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)粱侣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門羊壹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人齐婴,你說我怎么就攤上這事油猫。” “怎么了柠偶?”我有些...
    開封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵情妖,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我诱担,道長(zhǎng)毡证,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任蔫仙,我火速辦了婚禮料睛,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘摇邦。我一直安慰自己恤煞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開白布施籍。 她就那樣靜靜地躺著居扒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丑慎。 梳的紋絲不亂的頭發(fā)上喜喂,一...
    開封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天,我揣著相機(jī)與錄音立哑,去河邊找鬼夜惭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛铛绰,可吹牛的內(nèi)容都是我干的诈茧。 我是一名探鬼主播,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼捂掰,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼敢会!你這毒婦竟也來了曾沈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鸥昏,失蹤者是張志新(化名)和其女友劉穎塞俱,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吏垮,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡障涯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了膳汪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唯蝶。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖遗嗽,靈堂內(nèi)的尸體忽然破棺而出粘我,到底是詐尸還是另有隱情,我是刑警寧澤痹换,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布征字,位于F島的核電站,受9級(jí)特大地震影響娇豫,放射性物質(zhì)發(fā)生泄漏匙姜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一锤躁、第九天 我趴在偏房一處隱蔽的房頂上張望搁料。 院中可真熱鬧或详,春花似錦系羞、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至梧乘,卻和暖如春澎迎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背选调。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工夹供, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人仁堪。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓哮洽,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親弦聂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鸟辅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 摘要 這篇論文描述了Fork/Join框架的設(shè)計(jì)氛什、實(shí)現(xiàn)以及性能。這個(gè)框架通過(遞歸的)把問題劃分為子任務(wù)匪凉,然后并行...
    itonyli閱讀 1,166評(píng)論 0 5
  • 作者: 一字馬胡 轉(zhuǎn)載標(biāo)志 【2017-11-01】 更新日志 日期更新內(nèi)容備注2017-11-01新建文章V1...
    一字馬胡閱讀 7,372評(píng)論 9 134
  • 身邊的好友都在問我枪眉,為什么總是看到你在學(xué)習(xí)呢。我說再层,對(duì)呀贸铜,我只有學(xué)習(xí)了才能成長(zhǎng),成長(zhǎng)最快的方式是學(xué)習(xí)聂受,應(yīng)用萨脑。不去學(xué)...
    黃玉翠閱讀 302評(píng)論 0 0
  • 醒了。 睜開眼饺饭,入目的白色渤早,刺眼冰冷。濃重的消毒水氣味瘫俊,使我皺眉鹊杖。 一旁支架上的吊瓶已經(jīng)被護(hù)士拿走了,可左...
    毓夢(mèng)閱讀 203評(píng)論 0 0