久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術(shù)文章
文章詳情頁

輕輕松松吃透Java并發(fā)fork/join框架

瀏覽:2日期:2022-08-08 17:41:42
目錄一、概述二、說一說 RecursiveTask三、 Fork/Join框架基本使用四、工作順序圖1、ForkJoinPool構(gòu)造函數(shù)2、fork方法和join方法五、使用Fork/Join解決實(shí)際問題1.使用歸并算法解決排序問題2.使用Fork/Join運(yùn)行歸并算法

Fork / Join 是一個工具框架 , 其核心思想在于將一個大運(yùn)算切成多個小份 , 最大效率的利用資源 , 其主要涉及到三個類 : ForkJoinPool / ForkJoinTask / RecursiveTask

一、概述

java.util.concurrent.ForkJoinPool由Java大師Doug Lea主持編寫,它可以將一個大的任務(wù)拆分成多個子任務(wù)進(jìn)行并行處理,最后將子任務(wù)結(jié)果合并成最后的計(jì)算結(jié)果,并進(jìn)行輸出。本文中對Fork/Join框架的講解,基于JDK1.8+中的Fork/Join框架實(shí)現(xiàn),參考的Fork/Join框架主要源代碼也基于JDK1.8+。

文章將首先先談?wù)剅ecursive task,然后講解Fork/Join框架的基本使用;接著結(jié)合Fork/Join框架的工作原理來理解其中需要注意的使用要點(diǎn);最后再講解使用Fork/Join框架解決一些實(shí)際問題。

二、說一說 RecursiveTask

RecursiveTask 是一種 ForkJoinTask 的遞歸實(shí)現(xiàn) , 例如可以用于計(jì)算斐波那契數(shù)列 :

class Fibonacci extends RecursiveTask<Integer> { final int n; Fibonacci(int n) { this.n = n; } Integer compute() { if (n <= 1) return n; Fibonacci f1 = new Fibonacci(n - 1); f1.fork(); Fibonacci f2 = new Fibonacci(n - 2); return f2.compute() + f1.join(); } }

RecursiveTask 繼承了 ForkJoinTask 接口 ,其內(nèi)部有幾個主要的方法:

// Node 1 : 返回結(jié)果 , 存放最終結(jié)果V result;​// Node 2 : 抽象方法 compute , 用于計(jì)算最終結(jié)果protected abstract V compute();​// Node 3 : 獲取最終結(jié)果public final V getRawResult() {return result;}​// Node 4 : 最終執(zhí)行方法 , 這里是需要調(diào)用具體實(shí)現(xiàn)類computeprotected final boolean exec() { result = compute(); return true;}

常見使用方式:

@ public class ForkJoinPoolService extends RecursiveTask<Integer> {​ private static final int THRESHOLD = 2; //閥值 private int start; private int end;​ public ForkJoinPoolService(Integer start, Integer end) {this.start = start;this.end = end; }​ @Override protected Integer compute() {int sum = 0;boolean canCompute = (end - start) <= THRESHOLD;if (canCompute) { for (int i = start; i <= end; i++) {sum += i; }} else { int middle = (start + end) / 2; ForkJoinPoolService leftTask = new ForkJoinPoolService(start, middle); ForkJoinPoolService rightTask = new ForkJoinPoolService(middle + 1, end); //執(zhí)行子任務(wù) leftTask.fork(); rightTask.fork(); //等待子任務(wù)執(zhí)行完,并得到其結(jié)果 Integer rightResult = rightTask.join(); Integer leftResult = leftTask.join(); //合并子任務(wù) sum = leftResult + rightResult;}return sum; }​}三、 Fork/Join框架基本使用

這里是一個簡單的Fork/Join框架使用示例,在這個示例中我們計(jì)算了1-1001累加后的值:

/** * 這是一個簡單的Join/Fork計(jì)算過程,將1—1001數(shù)字相加 */public class TestForkJoinPool { private static final Integer MAX = 200; static class MyForkJoinTask extends RecursiveTask<Integer> {// 子任務(wù)開始計(jì)算的值private Integer startValue;// 子任務(wù)結(jié)束計(jì)算的值private Integer endValue;public MyForkJoinTask(Integer startValue , Integer endValue) { this.startValue = startValue; this.endValue = endValue;}@Overrideprotected Integer compute() { // 如果條件成立,說明這個任務(wù)所需要計(jì)算的數(shù)值分為足夠小了 // 可以正式進(jìn)行累加計(jì)算了 if(endValue - startValue < MAX) {System.out.println('開始計(jì)算的部分:startValue = ' + startValue + ';endValue = ' + endValue);Integer totalValue = 0;for(int index = this.startValue ; index <= this.endValue ; index++) { totalValue += index;}return totalValue; } // 否則再進(jìn)行任務(wù)拆分,拆分成兩個任務(wù) else {MyForkJoinTask subTask1 = new MyForkJoinTask(startValue, (startValue + endValue) / 2);subTask1.fork();MyForkJoinTask subTask2 = new MyForkJoinTask((startValue + endValue) / 2 + 1 , endValue);subTask2.fork();return subTask1.join() + subTask2.join(); }} } public static void main(String[] args) {// 這是Fork/Join框架的線程池ForkJoinPool pool = new ForkJoinPool();ForkJoinTask<Integer> taskFuture = pool.submit(new MyForkJoinTask(1,1001));try { Integer result = taskFuture.get(); System.out.println('result = ' + result);} catch (InterruptedException | ExecutionException e) { e.printStackTrace(System.out);} }}

以上代碼很簡單,在關(guān)鍵的位置有相關(guān)的注釋說明。這里本文再對以上示例中的要點(diǎn)進(jìn)行說明。首先看看以上示例代碼的可能執(zhí)行結(jié)果:

開始計(jì)算的部分:startValue = 1;endValue = 126開始計(jì)算的部分:startValue = 127;endValue = 251開始計(jì)算的部分:startValue = 252;endValue = 376開始計(jì)算的部分:startValue = 377;endValue = 501開始計(jì)算的部分:startValue = 502;endValue = 626開始計(jì)算的部分:startValue = 627;endValue = 751開始計(jì)算的部分:startValue = 752;endValue = 876開始計(jì)算的部分:startValue = 877;endValue = 1001result = 501501

四、工作順序圖

下圖展示了以上代碼的工作過程概要,但實(shí)際上Fork/Join框架的內(nèi)部工作過程要比這張圖復(fù)雜得多,例如如何決定某一個recursive task是使用哪條線程進(jìn)行運(yùn)行;再例如如何決定當(dāng)一個任務(wù)/子任務(wù)提交到Fork/Join框架內(nèi)部后,是創(chuàng)建一個新的線程去運(yùn)行還是讓它進(jìn)行隊(duì)列等待。

所以如果不深入理解Fork/Join框架的運(yùn)行原理,只是根據(jù)之上最簡單的使用例子觀察運(yùn)行效果,那么我們只能知道子任務(wù)在Fork/Join框架中被拆分得足夠小后,并且其內(nèi)部使用多線程并行完成這些小任務(wù)的計(jì)算后再進(jìn)行結(jié)果向上的合并動作,最終形成頂層結(jié)果。不急,一步一步來,我們先從這張概要的過程圖開始討論。

輕輕松松吃透Java并發(fā)fork/join框架

圖中最頂層的任務(wù)使用submit方式被提交到Fork/Join框架中,后者將前者放入到某個線程中運(yùn)行,工作任務(wù)中的compute方法的代碼開始對這個任務(wù)T1進(jìn)行分析。如果當(dāng)前任務(wù)需要累加的數(shù)字范圍過大(代碼中設(shè)定的是大于200),則將這個計(jì)算任務(wù)拆分成兩個子任務(wù)(T1.1和T1.2),每個子任務(wù)各自負(fù)責(zé)計(jì)算一半的數(shù)據(jù)累加,請參見代碼中的fork方法。如果當(dāng)前子任務(wù)中需要累加的數(shù)字范圍足夠小(小于等于200),就進(jìn)行累加然后返回到上層任務(wù)中。

1、ForkJoinPool構(gòu)造函數(shù)

ForkJoinPool有四個構(gòu)造函數(shù),其中參數(shù)最全的那個構(gòu)造函數(shù)如下所示:

public ForkJoinPool(int parallelism,ForkJoinWorkerThreadFactory factory,UncaughtExceptionHandler handler,boolean asyncMode) parallelism:可并行級別,F(xiàn)ork/Join框架將依據(jù)這個并行級別的設(shè)定,決定框架內(nèi)并行執(zhí)行的線程數(shù)量。并行的每一個任務(wù)都會有一個線程進(jìn)行處理,但是千萬不要將這個屬性理解成Fork/Join框架中最多存在的線程數(shù)量,也不要將這個屬性和ThreadPoolExecutor線程池中的corePoolSize、maximumPoolSize屬性進(jìn)行比較,因?yàn)镕orkJoinPool的組織結(jié)構(gòu)和工作方式與后者完全不一樣。而后續(xù)的討論中,讀者還可以發(fā)現(xiàn)Fork/Join框架中可存在的線程數(shù)量和這個參數(shù)值的關(guān)系并不是絕對的關(guān)聯(lián)(有依據(jù)但并不全由它決定)。 factory:當(dāng)Fork/Join框架創(chuàng)建一個新的線程時,同樣會用到線程創(chuàng)建工廠。只不過這個線程工廠不再需要實(shí)現(xiàn)ThreadFactory接口,而是需要實(shí)現(xiàn)ForkJoinWorkerThreadFactory接口。后者是一個函數(shù)式接口,只需要實(shí)現(xiàn)一個名叫newThread的方法。在Fork/Join框架中有一個默認(rèn)的ForkJoinWorkerThreadFactory接口實(shí)現(xiàn):DefaultForkJoinWorkerThreadFactory。 handler:異常捕獲處理器。當(dāng)執(zhí)行的任務(wù)中出現(xiàn)異常,并從任務(wù)中被拋出時,就會被handler捕獲。 asyncMode:這個參數(shù)也非常重要,從字面意思來看是指的異步模式,它并不是說Fork/Join框架是采用同步模式還是采用異步模式工作。Fork/Join框架中為每一個獨(dú)立工作的線程準(zhǔn)備了對應(yīng)的待執(zhí)行任務(wù)隊(duì)列,這個任務(wù)隊(duì)列是使用數(shù)組進(jìn)行組合的雙向隊(duì)列。即是說存在于隊(duì)列中的待執(zhí)行任務(wù),即可以使用先進(jìn)先出的工作模式,也可以使用后進(jìn)先出的工作模式。

輕輕松松吃透Java并發(fā)fork/join框架

當(dāng)asyncMode設(shè)置為ture的時候,隊(duì)列采用先進(jìn)先出方式工作;反之則是采用后進(jìn)先出的方式工作,該值默認(rèn)為false

......asyncMode ? FIFO_QUEUE : LIFO_QUEUE,......

ForkJoinPool還有另外兩個構(gòu)造函數(shù),一個構(gòu)造函數(shù)只帶有parallelism參數(shù),既是可以設(shè)定Fork/Join框架的最大并行任務(wù)數(shù)量;另一個構(gòu)造函數(shù)則不帶有任何參數(shù),對于最大并行任務(wù)數(shù)量也只是一個默認(rèn)值——當(dāng)前操作系統(tǒng)可以使用的CPU內(nèi)核數(shù)量(Runtime.getRuntime().availableProcessors())。實(shí)際上ForkJoinPool還有一個私有的、原生構(gòu)造函數(shù),之上提到的三個構(gòu)造函數(shù)都是對這個私有的、原生構(gòu)造函數(shù)的調(diào)用。

......private ForkJoinPool(int parallelism, ForkJoinWorkerThreadFactory factory, UncaughtExceptionHandler handler, int mode, String workerNamePrefix) {this.workerNamePrefix = workerNamePrefix;this.factory = factory;this.ueh = handler;this.config = (parallelism & SMASK) | mode;long np = (long)(-parallelism); // offset ctl countsthis.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK); }......

如果你對Fork/Join框架沒有特定的執(zhí)行要求,可以直接使用不帶有任何參數(shù)的構(gòu)造函數(shù)。也就是說推薦基于當(dāng)前操作系統(tǒng)可以使用的CPU內(nèi)核數(shù)作為Fork/Join框架內(nèi)最大并行任務(wù)數(shù)量,這樣可以保證CPU在處理并行任務(wù)時,盡量少發(fā)生任務(wù)線程間的運(yùn)行狀態(tài)切換(實(shí)際上單個CPU內(nèi)核上的線程間狀態(tài)切換基本上無法避免,因?yàn)椴僮飨到y(tǒng)同時運(yùn)行多個線程和多個進(jìn)程)。

2、fork方法和join方法

Fork/Join框架中提供的fork方法和join方法,可以說是該框架中提供的最重要的兩個方法,它們和parallelism“可并行任務(wù)數(shù)量”配合工作,可以導(dǎo)致拆分的子任務(wù)T1.1、T1.2甚至TX在Fork/Join框架中不同的運(yùn)行效果。例如TX子任務(wù)或等待其它已存在的線程運(yùn)行關(guān)聯(lián)的子任務(wù),或在運(yùn)行TX的線程中“遞歸”執(zhí)行其它任務(wù),又或者啟動一個新的線程運(yùn)行子任務(wù)……

fork方法用于將新創(chuàng)建的子任務(wù)放入當(dāng)前線程的work queue隊(duì)列中,F(xiàn)ork/Join框架將根據(jù)當(dāng)前正在并發(fā)執(zhí)行ForkJoinTask任務(wù)的ForkJoinWorkerThread線程狀態(tài),決定是讓這個任務(wù)在隊(duì)列中等待,還是創(chuàng)建一個新的ForkJoinWorkerThread線程運(yùn)行它,又或者是喚起其它正在等待任務(wù)的ForkJoinWorkerThread線程運(yùn)行它。

這里面有幾個元素概念需要注意,F(xiàn)orkJoinTask任務(wù)是一種能在Fork/Join框架中運(yùn)行的特定任務(wù),也只有這種類型的任務(wù)可以在Fork/Join框架中被拆分運(yùn)行和合并運(yùn)行。ForkJoinWorkerThread線程是一種在Fork/Join框架中運(yùn)行的特性線程,它除了具有普通線程的特性外,最主要的特點(diǎn)是每一個ForkJoinWorkerThread線程都具有一個獨(dú)立的任務(wù)等待隊(duì)列(work queue),這個任務(wù)隊(duì)列用于存儲在本線程中被拆分的若干子任務(wù)。

輕輕松松吃透Java并發(fā)fork/join框架

join方法用于讓當(dāng)前線程阻塞,直到對應(yīng)的子任務(wù)完成運(yùn)行并返回執(zhí)行結(jié)果。或者,如果這個子任務(wù)存在于當(dāng)前線程的任務(wù)等待隊(duì)列(work queue)中,則取出這個子任務(wù)進(jìn)行“遞歸”執(zhí)行。其目的是盡快得到當(dāng)前子任務(wù)的運(yùn)行結(jié)果,然后繼續(xù)執(zhí)行。

五、使用Fork/Join解決實(shí)際問題

之前所舉的的例子是使用Fork/Join框架完成1-1000的整數(shù)累加。這個示例如果只是演示Fork/Join框架的使用,那還行,但這種例子和實(shí)際工作中所面對的問題還有一定差距。本篇文章我們使用Fork/Join框架解決一個實(shí)際問題,就是高效排序的問題。

1.使用歸并算法解決排序問題

排序問題是我們工作中的常見問題。目前也有很多現(xiàn)成算法是為了解決這個問題而被發(fā)明的,例如多種插值排序算法、多種交換排序算法。而并歸排序算法是目前所有排序算法中,平均時間復(fù)雜度較好(O(nlgn)),算法穩(wěn)定性較好的一種排序算法。它的核心算法思路將大的問題分解成多個小問題,并將結(jié)果進(jìn)行合并。

輕輕松松吃透Java并發(fā)fork/join框架

整個算法的拆分階段,是將未排序的數(shù)字集合,從一個較大集合遞歸拆分成若干較小的集合,這些較小的集合要么包含最多兩個元素,要么就認(rèn)為不夠小需要繼續(xù)進(jìn)行拆分。

那么對于一個集合中元素的排序問題就變成了兩個問題:1、較小集合中最多兩個元素的大小排序;2、如何將兩個有序集合合并成一個新的有序集合。第一個問題很好解決,那么第二個問題是否會很復(fù)雜呢?實(shí)際上第二個問題也很簡單,只需要將兩個集合同時進(jìn)行一次遍歷即可完成——比較當(dāng)前集合中最小的元素,將最小元素放入新的集合,它的時間復(fù)雜度為O(n):

輕輕松松吃透Java并發(fā)fork/join框架

以下是歸并排序算法的簡單實(shí)現(xiàn):

package test.thread.pool.merge;import java.util.Arrays;import java.util.Random;/** * 歸并排序 * @author yinwenjie */public class Merge1 { private static int MAX = 10000; private static int inits[] = new int[MAX]; // 這是為了生成一個數(shù)量為MAX的隨機(jī)整數(shù)集合,準(zhǔn)備計(jì)算數(shù)據(jù) // 和算法本身并沒有什么關(guān)系 static {Random r = new Random();for(int index = 1 ; index <= MAX ; index++) { inits[index - 1] = r.nextInt(10000000);} } public static void main(String[] args) {long beginTime = System.currentTimeMillis();int results[] = forkits(inits); long endTime = System.currentTimeMillis();// 如果參與排序的數(shù)據(jù)非常龐大,記得把這種打印方式去掉System.out.println('耗時=' + (endTime - beginTime) + ' | ' + Arrays.toString(results)); } // 拆分成較小的元素或者進(jìn)行足夠小的元素集合的排序 private static int[] forkits(int source[]) {int sourceLen = source.length;if(sourceLen > 2) { int midIndex = sourceLen / 2; int result1[] = forkits(Arrays.copyOf(source, midIndex)); int result2[] = forkits(Arrays.copyOfRange(source, midIndex , sourceLen)); // 將兩個有序的數(shù)組,合并成一個有序的數(shù)組 int mer[] = joinInts(result1 , result2); return mer;} // 否則說明集合中只有一個或者兩個元素,可以進(jìn)行這兩個元素的比較排序了else { // 如果條件成立,說明數(shù)組中只有一個元素,或者是數(shù)組中的元素都已經(jīng)排列好位置了 if(sourceLen == 1|| source[0] <= source[1]) {return source; } else {int targetp[] = new int[sourceLen];targetp[0] = source[1];targetp[1] = source[0];return targetp; }} } /** * 這個方法用于合并兩個有序集合 * @param array1 * @param array2 */ private static int[] joinInts(int array1[] , int array2[]) {int destInts[] = new int[array1.length + array2.length];int array1Len = array1.length;int array2Len = array2.length;int destLen = destInts.length;// 只需要以新的集合destInts的長度為標(biāo)準(zhǔn),遍歷一次即可for(int index = 0 , array1Index = 0 , array2Index = 0 ; index < destLen ; index++) { int value1 = array1Index >= array1Len?Integer.MAX_VALUE:array1[array1Index]; int value2 = array2Index >= array2Len?Integer.MAX_VALUE:array2[array2Index]; // 如果條件成立,說明應(yīng)該取數(shù)組array1中的值 if(value1 < value2) {array1Index++;destInts[index] = value1; } // 否則取數(shù)組array2中的值 else {array2Index++;destInts[index] = value2; }}return destInts; }}

以上歸并算法對1萬條隨機(jī)數(shù)進(jìn)行排序只需要2-3毫秒,對10萬條隨機(jī)數(shù)進(jìn)行排序只需要20毫秒左右的時間,對100萬條隨機(jī)數(shù)進(jìn)行排序的平均時間大約為160毫秒(這還要看隨機(jī)生成的待排序數(shù)組是否本身的凌亂程度)。可見歸并算法本身是具有良好的性能的。使用JMX工具和操作系統(tǒng)自帶的CPU監(jiān)控器監(jiān)視應(yīng)用程序的執(zhí)行情況,可以發(fā)現(xiàn)整個算法是單線程運(yùn)行的,且同一時間CPU只有單個內(nèi)核在作為主要的處理內(nèi)核工作:

JMX中觀察到的線程情況:

輕輕松松吃透Java并發(fā)fork/join框架

CPU的運(yùn)作情況:

輕輕松松吃透Java并發(fā)fork/join框架

2.使用Fork/Join運(yùn)行歸并算法

但是隨著待排序集合中數(shù)據(jù)規(guī)模繼續(xù)增大,以上歸并算法的代碼實(shí)現(xiàn)就有一些力不從心了,例如以上算法對1億條隨機(jī)數(shù)集合進(jìn)行排序時,耗時為27秒左右。

接著我們可以使用Fork/Join框架來優(yōu)化歸并算法的執(zhí)行性能,將拆分后的子任務(wù)實(shí)例化成多個ForkJoinTask任務(wù)放入待執(zhí)行隊(duì)列,并由Fork/Join框架在多個ForkJoinWorkerThread線程間調(diào)度這些任務(wù)。如下圖所示:

輕輕松松吃透Java并發(fā)fork/join框架

以下為使用Fork/Join框架后的歸并算法代碼,請注意joinInts方法中對兩個有序集合合并成一個新的有序集合的代碼,是沒有變化的可以參見本文上一小節(jié)中的內(nèi)容。所以在代碼中就不再贅述了:

....../** * 使用Fork/Join框架的歸并排序算法 * @author yinwenjie */public class Merge2 { private static int MAX = 100000000; private static int inits[] = new int[MAX]; // 同樣進(jìn)行隨機(jī)隊(duì)列初始化,這里就不再贅述了 static {...... } public static void main(String[] args) throws Exception { // 正式開始long beginTime = System.currentTimeMillis();ForkJoinPool pool = new ForkJoinPool();MyTask task = new MyTask(inits);ForkJoinTask<int[]> taskResult = pool.submit(task);try { taskResult.get();} catch (InterruptedException | ExecutionException e) { e.printStackTrace(System.out);}long endTime = System.currentTimeMillis();System.out.println('耗時=' + (endTime - beginTime)); } /** * 單個排序的子任務(wù) * @author yinwenjie */ static class MyTask extends RecursiveTask<int[]> {private int source[];public MyTask(int source[]) { this.source = source;}/* (non-Javadoc) * @see java.util.concurrent.RecursiveTask#compute() */@Overrideprotected int[] compute() { int sourceLen = source.length; // 如果條件成立,說明任務(wù)中要進(jìn)行排序的集合還不夠小 if(sourceLen > 2) {int midIndex = sourceLen / 2;// 拆分成兩個子任務(wù)MyTask task1 = new MyTask(Arrays.copyOf(source, midIndex));task1.fork();MyTask task2 = new MyTask(Arrays.copyOfRange(source, midIndex , sourceLen));task2.fork();// 將兩個有序的數(shù)組,合并成一個有序的數(shù)組int result1[] = task1.join();int result2[] = task2.join();int mer[] = joinInts(result1 , result2);return mer; } // 否則說明集合中只有一個或者兩個元素,可以進(jìn)行這兩個元素的比較排序了 else {// 如果條件成立,說明數(shù)組中只有一個元素,或者是數(shù)組中的元素都已經(jīng)排列好位置了if(sourceLen == 1 || source[0] <= source[1]) { return source;} else { int targetp[] = new int[sourceLen]; targetp[0] = source[1]; targetp[1] = source[0]; return targetp;} }}private int[] joinInts(int array1[] , int array2[]) { // 和上文中出現(xiàn)的代碼一致} }}

使用Fork/Join框架優(yōu)化后,同樣執(zhí)行1億條隨機(jī)數(shù)的排序處理時間大約在14秒左右,當(dāng)然這還和待排序集合本身的凌亂程度、CPU性能等有關(guān)系。但總體上這樣的方式比不使用Fork/Join框架的歸并排序算法在性能上有30%左右的性能提升。以下為執(zhí)行時觀察到的CPU狀態(tài)和線程狀態(tài):

JMX中的內(nèi)存、線程狀態(tài):

輕輕松松吃透Java并發(fā)fork/join框架

CPU使用情況:

輕輕松松吃透Java并發(fā)fork/join框架

除了歸并算法代碼實(shí)現(xiàn)內(nèi)部可優(yōu)化的細(xì)節(jié)處,使用Fork/Join框架后,我們基本上在保證操作系統(tǒng)線程規(guī)模的情況下,將每一個CPU內(nèi)核的運(yùn)算資源同時發(fā)揮了出來。

到此這篇關(guān)于輕輕松松吃透Java并發(fā)fork/join框架的文章就介紹到這了,更多相關(guān)Java fork/join框架內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 美女久久 | 蜜臀视频在线观看 | 在线观看国产www | 日韩一区二区三区在线观看 | 99热首页| 亚洲久悠悠色悠在线播放 | 欧美精品中文字幕久久二区 | 成年人在线视频 | 黄视频免费在线 | 国产一区不卡 | 97在线视频免费 | 国产精品成人在线观看 | 亚洲一区二区三区四区五区午夜 | 精品91在线视频 | 久草网在线视频 | 国产日韩欧美一区 | 亚洲成人精品在线观看 | 中文字幕综合 | 国产一区二区精品久久 | 激情视频在线观看免费 | 欧美日韩亚洲国产 | 国产看片网站 | 免费激情网站 | 亚洲日本中文 | 奇米成人影视 | 亚洲精品一区二三区不卡 | 免费视频一区 | 久久久久久久一区 | 日本福利网站 | 日韩午夜视频在线观看 | 欧美久久一级特黄毛片 | 在线小视频 | 成人av片在线观看 | 97av | 亚洲天堂中文字幕 | 久久99这里只有精品 | 中文字幕第一页在线 | 久久国产精品99久久久久久老狼 | 亚洲骚片| 欧美成人精品一区 | 在线成人免费 | 国产精品一品二区三区的使用体验 | 成人午夜在线 | 欧美日韩不卡在线 | 超碰国产一区 | 精品国产一区二区三区免费 | 欧美日韩中文字幕在线 | 日韩精品一区二区三区在线播放 | 亚洲国产精品久久久 | 永久精品 | 欧美亚洲天堂 | 成人精品视频在线观看 | 欧美成人免费视频 | 久久无码精品一区二区三区 | 国产欧美一区二区精品忘忧草 | 2018国产精品| 91精品久久久久久久91蜜桃 | 91在线视频免费观看 | 女同理伦片在线观看禁男之园 | 91精品中文字幕一区二区三区 | 亚洲欧美激情视频 | 一区二区三区高清不卡 | avmans最新导航地址 | 日韩精品在线播放 | www.毛片| 亚洲社区在线观看 | 99国产精品视频免费观看一公开 | 蜜桃中文字幕 | 久久精品这里热有精品 | 正在播放国产一区 | 一区二区三区精品视频 | 日本综合久久 | 国产精品国产三级国产aⅴ入口 | 欧美在线观看一区 | 欧美第一区 | 亚洲色域网 | 一区二区日韩精品 | 久久精品国产v日韩v亚洲 | 美日韩精品视频 | 99久久精品免费看国产四区 | 91精品福利 | 精品国产99 | 久久成人精品视频 | 二区在线观看 | 日韩视频网站在线观看 | 欧美黄色网 | 互换娇妻呻吟hd中文字幕 | 国产一级毛片在线视频 | 国产精品久久久久久久久久久久冷 | 日韩在线观看第一页 | 米奇影视7777 | 伊人精品视频在线观看 | 美女一区二区三区在线观看 | 国产视频精品一区二区三区 | 免费三级电影网站 | 欧洲成人午夜免费大片 | 夜夜夜夜夜操 | 日韩欧美成人一区二区三区 | 91久久久久久久久久久久久 | 天天色天天色 | 日本美女一区二区 | 国产麻豆乱码精品一区二区三区 | 免费一级在线观看 | www.色综合 | 日日视频 | 在线二区 | 色官网| 91免费看 | 在线观看精品91福利 | 久久久久久91亚洲精品中文字幕 | 国产欧美精品区一区二区三区 | 欧美久久久精品 | 精品无人乱码一区二区三区 | 国产麻豆一区二区三区 | 亚洲精品a在线观看 | 免费v片在线观看 | 欧美亚洲综合久久 | 欧美日韩不卡合集视频 | 久久兔费看a级 | 久久成人一区二区 | 亚洲女人天堂成人av在线 | 国产精品久久久99 | 亚洲毛片在线观看 | 亚洲成a人| 日本在线不卡视频 | 国产v日产∨综合v精品视频 | 欧美国产视频 | 精品国产乱码久久久久久闺蜜 | 97久久精品午夜一区二区 | 亚洲欧洲一区 | 91观看| 狠狠干狠狠干 | www.44181com| 国产二区精品 | 超碰在线人人 | 激情久久久久 | 久久综合久久综合久久综合 | 国产精品久久久久久久久久久久久久久久 | 欧美在线一区二区 | 久久精品亚洲 | 亚洲一区视频在线 | 精品国产精品三级精品av网址 | 日韩中文字幕在线观看 | 色成人免费网站 | 91精品国产欧美一区二区成人 | 精品视频三区 | 狠狠干狠狠干 | 亚洲成人精品在线观看 | 欧美激情视频一区二区三区在线播放 | 国产成人精品一区二区三区视频 | 日韩性欧美 | 精品视频一区二区 | 精品久久久久久久久久久久久 | 免费av毛片| 久久国内免费视频 | 久久久高清| 久久久久久久av | 日本狠狠操 | 亚洲精品视频播放 | 欧美一级做性受免费大片免费 | 免费看的黄色 | 免费成人av | 国产欧美精品一区二区 | 久久伊99综合婷婷久久伊 | 国产精品久久久久毛片软件 | 激情欧美一区二区三区中文字幕 | 久久免费小视频 | 国产一区免费 | 国产片侵犯亲女视频播放 | 亚洲国产精品久久久 | 中文视频在线 | 四虎影音 | 日韩成人中文字幕 | 日本久久久久久 | 性色国产| 日日操视频 | 美女h视频 | 久久99影视 | 亚洲精品久久久久久久久久久 | 在线播放国产一区二区三区 | 美女高潮久久久 | 亚洲一区二区三区免费在线观看 | 一级黄色片视频 | 日本亚洲欧美 | 国产精品一区二区三区四区 | 国产成人精品一区二区视频免费 | 美女一级毛片 | 操操操av| 成人精品久久久 | 亚洲精品乱码久久久久久蜜桃不爽 | 久久影院一区 | 一区二区三 | 美女福利网站 | 国产在线二区 | 香蕉久久夜色精品国产使用方法 | 欧美一区二区三区精品免费 | 色欧美片视频在线观看 | 中文在线a在线 | 国产麻豆乱码精品一区二区三区 | 一级做a爰 | 欧美精品免费在线观看 | 国产xxxx成人精品免费视频频 | 亚洲人成在线播放 | www.色综合| 欧美日韩一区二区三区在线观看 | 欧美激情在线播放 | 欧美国产精品一区二区三区 | 日韩一区中文 | 久久久久久这里只有精品 | 亚洲视频综合 | 91麻豆精品国产91久久久资源速度 | 成人免费视频网站 | 欧美成在线观看 | 亚洲综合视频在线观看 | 国产精品美女久久久久久久久久久 | 久久男人 | 欧美激情视频一区二区三区在线播放 | 一区不卡| 久久久久久网站 | 国产精品久久久久国产a级 欧美日本韩国一区二区 | a在线免费观看 | 国产情侣在线视频 | 精品国产一区二区三区久久久蜜月 | 国产女爽123视频.cno | 一区二区三区四区视频 | 欧美日韩一二三 | 国产精品久久久久久吹潮 | h片在线免费观看 | 精品一区av | 中文二区 | 四虎永久免费影视 | 玖玖国产精品视频 | 天天av天天操 | 人人人人人你人人人人人 | 午夜视频福利在线观看 | 国产高清在线观看 | 天天天综合网 | 精久久 | 国产成人精品免费视频大全 | 精品一二区 | 久久1区 | 在线天堂新版最新版在线8 www.国产欧美 | 99热影院| 久久久久久久久久久免费视频 | 欧美三级免费观看 | 亚洲美女视频 | 久久国产高清 | 一本一道久久久a久久久精品91 | 精品成人在线 | 国内精品视频一区二区三区八戒 | 99re6热在线精品视频播放 | 日韩电影一区二区在线观看 | 亚洲视频一区在线 | av一区二区三区四区 | 亚洲精品一区二区三区不 | 国产精品第一国产精品 | 一区二区日韩 | 亚洲成熟少妇视频在线观看 | 亚洲免费视频大全 | 亚洲国产精品久久久久久 | 中文字幕第十二页 | 超级乱淫片国语对白免费视频 | 中国大陆高清aⅴ毛片 | 久久久精品国产 | 欧美精品一区在线观看 | 一区二区在线电影 | 欧美 国产精品 | 久久99精品久久久久久琪琪 | 国产精品久久久久久久久动漫 | 91精品久久久久久久久久久 | 日韩不卡一区二区三区 | 不卡一二 | 午夜a级理论片915影院 | 欧洲免费毛片 | 欧洲一区二区三区 | 久久久久一区二区三区 | 久久国产精品99久久久久久牛牛 | 黄色毛片免费看 | 亚洲欧美一区二区三区在线 | 日韩精品免费在线观看 | 国产精品久久一区二区三区 | 国产高清一区二区 | 日韩欧美精品一区二区三区 | 日本少妇bbbb爽爽bbb美 | 日韩av福利 | 成年人福利| 天堂福利影院 | 一级欧美 | 国产二区三区 | 欧美福利 | 成人在线播放 | 精品久久久久久久久久 | 免费网站国产 | 中文字幕亚洲区 | 99成人| 天天干夜夜骑 | 最新的黄色网址 | 亚洲精品在线免费播放 | 欧美午夜在线观看 | 亚洲欧美影院 | 色欧美日韩 | 美女毛片 | 国产欧美日韩综合精品一区二区 | 免费视频爱爱太爽了 | 成人亚洲视频 | 香蕉三级 | 日韩免费观看视频 | 一区网站 | 草久在线视频 | av黄色在线 | 亚洲a网 | 日韩视频免费 | 国产91精品一区二区绿帽 | 一区二区三区免费网站 | 三级av网站 | 久久久xxxx| 欧美激情国产日韩精品一区18 | 簧片毛片 | 一区二区三区av | 精品一区二区三区四区五区 | 色吧av| 国内久久精品 | 国产激情综合五月久久 | 精品自拍视频 | 男女视频在线观看 | 老司机深夜福利视频 | 日本天天操 | 国产在线免费 | 午夜a级理论片915影院 | 精品三区| 在线观看av网站永久 | 免费亚洲婷婷 | 日韩一区二区三区精品 | 不卡免费在线视频 | av在线一区二区三区 | 亚洲视频在线播放 | 久久精品综合 | 在线观看国产小视频 | 天天射美女| 欧美a网站 | 思热99re视热频这里只精品 | 午夜免费观看网站 | 久久久久久亚洲精品 | 国产成人精品一区 | 国产91综合一区在线观看 | www.日韩 | 国产激情一区二区三区 | 九色91视频 | 狠狠狠狠狠狠干 | 亚洲一区二区三区免费在线 | 国产欧美在线观看 | 51国产午夜精品免费视频 | 国产一区二区三区免费 | 久久国产精品久久久久久久久久 | 国产一区中文字幕 | 日韩午夜免费视频 | 成人免费网站在线观看 | av高清在线免费观看 | 日韩一区二区久久 | 欧美精品免费在线 | 国产精品九九九 | 午夜精品久久 | 久久精品久久久久 | 午夜家庭影院 | 亚洲美女一区 | av日韩在线看 | 国产精品久久久久久av公交车 | 一区视频 | 日本一区二区不卡 | 精品一区二区三区在线观看 | 91精品国产综合久久香蕉922 | 日韩免费 | 欧美亚洲国产一区 | 精品999| 成人免费福利视频 | 亚洲午夜精品在线观看 | 99福利视频 | 综合久久网| 欧美一级毛片日韩一级 | 亚洲人久久 | 伊人网站 | www.avtt天堂网 | 精品视频一区二区三区 | 最新免费视频 | 欧美视频在线播放 | 日本久久久久久 | 国产一区不卡视频 | 亚洲伦理 | 91在线免费视频 | 日韩激情视频一区 | 国产精品久久一区 | 欧洲视频一区二区三区 | 黄色免费在线观看 | 99在线免费观看 | 亚洲国产欧美一区二区三区久久 | 亚洲看片 | 亚洲成人一区二区 | 99影视| 欧美一区二区三区在线观看视频 | 亚洲一区日韩 | 天堂免费在线观看视频 | 亚洲人成网亚洲欧洲无码 | 9久9久 | 精品国产成人 | 日日摸天天做天天添天天欢 | 日韩中文字幕无码一区二区三区 | 久久精品毛片 | 久久精品中文 | 欧美亚洲免费 | 一区免费看 | 精品日韩中文字幕 | 精品一区二区三区蜜桃 | 日韩一区二区三区av | 欧美一区二区三区免费电影 | 色综合久久88色综合天天 | 久久国产精品无码网站 | 国产特一级黄色片 | 狠狠躁夜夜躁人人爽天天天天97 | 国产精品九九九 | 久久精品123| 国产成人av在线 | 久久精品一区二区 | 亚洲乱码一区二区三区在线观看 | 国产精品久久久久久久美男 | 九色av| 亚洲啊v在线 | 国产超碰人人模人人爽人人添 | 成人激情视频在线免费观看 | 凹凸日日摸日日碰夜夜爽孕妇 | 久久99精品久久久 | 欧美一区二区三区 | 亚洲一区二区三区爽爽爽爽爽 | 国产精品视频免费看 | 精品在线不卡 | 国产在线观看91一区二区三区 | 天天干,夜夜操 | 成人在线免费视频 | 久久se精品一区精品二区 | 欧美啊v| 国精品一区 | jizz中国zz女人18高潮 | 天天综合7799精品影视 | 久久9999| 欧美日韩激情在线一区二区三区 | 日韩一区二区成人 | 欧美日韩一区二区三区在线观看 | 国产综合久久久久久鬼色 | 一级毛片黄 | 综合自拍偷拍 | 亚洲不卡| 99热.com | 成人精品三级av在线看 | 在线国产视频 | 香蕉久久久久久 | 亚洲国产成人av | 国内精品一区二区三区 | 黄色片地址 | 久久久a| 在线区 | 日韩av视屏 | 成人黄色一级网站 | 国产成人精品一区二区三区四区 | 小情侣高清国产在线播放 | 欧美激情视频一区二区三区在线播放 | 亚洲精品乱码久久久久久蜜糖图片 | 国产高清视频一区二区 | 狠狠爱天天操 | 亚洲国产精品t66y | 亚洲成人精品一区 | 麻豆精品国产传媒 | 亚洲天堂一区二区 | 一区二区三区四区在线播放 | 国产一区久久久 | 亚洲精品乱码久久久久久久久 | 亚洲天天操 | 欧美在线一区二区 | 国产一区亚洲 | 青青草久草在线 | 在线精品国产 | 精品国产一区二区国模嫣然 | 精品国产一区二区三区久久久蜜臀 | 伊人二区 | 一区二区久久 | 日韩欧美视频 | 九九亚洲精品 | 在线日韩欧美 | 国产精品69毛片高清亚洲 | 久久久久国产一区二区三区 | 91在线观看免费 | 国产主播一区 | 狠狠躁夜夜躁人人爽天天天天97 | 亚洲免费观看 | 久久窝 | 欧美日韩综合视频 | 欧洲精品一区 | 亚洲另类视频 | 日产久久| 久草福利资源 | 男女啪啪无遮挡 | 国产精品二区三区 | 欧美八区 | 中国一级大黄大黄大色毛片 | 日干夜操| 亚洲另类视频 | 中文字幕在线观看av | 久久精品国产一区 | 九九re热| 成人在线看片 | 国产精品日韩专区 | 躁躁躁日躁夜夜躁 | 国产综合亚洲精品一区二 | 亚洲国产精品久久 | 欧美1级| 九色av | 狠狠操天天干 | 精品久久久久久久久久久下田 | 亚洲精品一区二区三区蜜桃久 | www.日韩系列 | 久久免费视频网 | 五月天婷婷精品 | 伊人精品视频在线观看 | www.99热| 久久丁香 | 国产精品久久久久久吹潮 | 做a视频在线观看 | 麻豆国产一区二区三区四区 | 日日操夜夜操免费视频 | 青青草一区 | 国产精品.xx视频.xxtv | 亚洲免费在线观看 | 日本一区二区三区四区 | 91香蕉视频 | 精品中文字幕在线 | 日韩综合一区 | 色综合天天综合网国产成人网 | 国产成人精品在线 | 一级毛片网 | 成人小视频在线观看 | 免费成人在线观看 | 午夜私人影院在线观看 | 在线免费观看黄色 | 在线观看免费视频日韩 | 国产一区二区三区久久久 | 黄色小视频免费观看 | 亚洲女人天堂成人av在线 | 香蕉视频黄色 | 国产欧美在线视频 | 成人免费在线播放 | 久久精品中文字幕 | 欧美一级艳片视频免费观看 | 国产 一区 | 国产免费久久 | 在线免费看a | 亚洲视频在线观看一区二区三区 | 99视频网站 | 可以在线观看的av网站 | 国产日产精品一区二区三区四区 | 亚洲一区二区三区免费 | 看真人视频a级毛片 | 成人av福利 | 在线观看日韩 | 视频一区在线播放 | 成年人网站免费在线观看 | 一级片av | 久久久久久国产精品 | 龙珠z国语291集普通话 | 国产精品污www一区二区三区 | 国产激情在线 | 国产精品久久在线观看 | 成人欧美一区二区三区黑人孕妇 | 成人欧美一区二区三区黑人孕妇 | av免费网站在线观看 | 中文字幕在线三区 | 久久久久国产精品www | 国产高清在线不卡 | 午夜免费视频 | 伊人成人222| 亚洲福利免费 | 亚洲一区二区三区国产 | 中文字幕 在线观看 | 欲色av | 在线观看成人av | 午夜在线电影 | 日本黄色毛片 | 久久久精品视频免费观看 | 日韩欧美在线中文字幕 | 91精品国产91久久久久久吃药 | 日韩欧美在线视频 | 成人在线免费观看视频 | 国产精品乱码一区二区三区 | 日韩欧美国产一区二区三区 | 国产h在线 | 日韩成人免费 | 精品久久久久久亚洲综合网 | 91福利电影在线观看 | 一色一黄视频 | 在线视频这里只有精品 | 久热av在线 | 色av色av色av| 久久久精品久久久久 | 日韩电影一区二区在线观看 | www.夜夜操.com | 国产一级黄片毛片 | 夜本色| 久久久久亚洲av毛片大全 | 免费看的av | 99热精品在线 | 国产亚洲精品成人av久久ww | 中文视频在线 | 国产精品成人一区二区 | 免费观看特级毛片 | 日韩不卡 | 91资源在线观看 | 久久国产精品视频 | 亚洲不卡视频 |