精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

阻塞隊列—PriorityBlockingQueue源碼分析

開發 前端
PriorityBlockingQueue 優先級隊列,線程安全(添加、讀取都進行了加鎖)、無界、讀阻塞的隊列,底層采用的堆結構實現(二叉樹),默認是小根堆,最小的或者最大的元素會一直置頂,每次獲取都取最頂端的數據

 前言


PriorityBlockingQueue 優先級隊列,線程安全(添加、讀取都進行了加鎖)、無界、讀阻塞的隊列,底層采用的堆結構實現(二叉樹),默認是小根堆,最小的或者最大的元素會一直置頂,每次獲取都取最頂端的數據

隊列創建

小根堆

  1. PriorityBlockingQueue<Integer> concurrentLinkedQueue = new PriorityBlockingQueue<Integer>(); 

大根堆

  1. PriorityBlockingQueue<Integer> concurrentLinkedQueue = new PriorityBlockingQueue<Integer>(10, new Comparator<Integer>() { 
  2.  @Override 
  3.  public int compare(Integer o1, Integer o2) { 
  4.   return o2 - o1; 
  5.  } 
  6. }); 

 應用場景

有任務要執行,可以對任務加一個優先級的權重,這樣隊列會識別出來,對該任務優先進行出隊。

我們來看一個具體例子,例子中定義了一個將要放入“優先阻塞隊列”的任務類,并且定義了一個任務工場類和一個任務執行類,在任務工場類中產生了各種不同優先級的任務,將其添加到隊列中,在任務執行類中,任務被一個個取出并執行。

  1. package com.niuh.queue.priority; 
  2.  
  3. import java.util.ArrayList; 
  4. import java.util.List; 
  5. import java.util.Queue; 
  6. import java.util.Random; 
  7. import java.util.concurrent.ExecutorService; 
  8. import java.util.concurrent.Executors; 
  9. import java.util.concurrent.PriorityBlockingQueue; 
  10. import java.util.concurrent.TimeUnit; 
  11.  
  12. /** 
  13.  * <p> 
  14.  * PriorityBlockingQueue使用示例 
  15.  * </p> 
  16.  */ 
  17. public class PriorityBlockingQueueDemo { 
  18.  
  19.     public static void main(String[] args) throws Exception { 
  20.         Random random = new Random(47); 
  21.         ExecutorService exec = Executors.newCachedThreadPool(); 
  22.         PriorityBlockingQueue<Runnable> queue = new PriorityBlockingQueue<>(); 
  23.         exec.execute(new PrioritizedTaskProducer(queue, exec)); // 這里需要注意,往PriorityBlockingQueue中添加任務和取出任務的 
  24.         exec.execute(new PrioritizedTaskConsumer(queue)); // 步驟是同時進行的,因而輸出結果并不一定是有序的 
  25.     } 
  26.  
  27. class PrioritizedTask implements Runnable, Comparable<PrioritizedTask> { 
  28.     private Random random = new Random(47); 
  29.     private static int counter = 0; 
  30.     private final int id = counter++; 
  31.     private final int priority; 
  32.  
  33.     protected static List<PrioritizedTask> sequence = new ArrayList<>(); 
  34.  
  35.     public PrioritizedTask(int priority) { 
  36.         this.priority = priority; 
  37.         sequence.add(this); 
  38.     } 
  39.  
  40.     @Override 
  41.     public int compareTo(PrioritizedTask o) { 
  42.         return priority < o.priority ? 1 : (priority > o.priority ? -1 : 0);  // 定義優先級計算方式 
  43.     } 
  44.  
  45.     @Override 
  46.     public void run() { 
  47.         try { 
  48.             TimeUnit.MILLISECONDS.sleep(random.nextInt(250)); 
  49.         } catch (InterruptedException e) { 
  50.         } 
  51.         System.out.println(this); 
  52.     } 
  53.  
  54.     @Override 
  55.     public String toString() { 
  56.         return String.format("[%1$-3d]", priority) + " Task " + id; 
  57.     } 
  58.  
  59.     public String summary() { 
  60.         return "(" + id + ": " + priority + ")"
  61.     } 
  62.  
  63.     public static class EndSentinel extends PrioritizedTask { 
  64.         private ExecutorService exec
  65.  
  66.         public EndSentinel(ExecutorService exec) { 
  67.             super(-1); 
  68.             this.exec = exec
  69.         } 
  70.  
  71.         @Override 
  72.         public void run() { 
  73.             int count = 0; 
  74.             for (PrioritizedTask pt : sequence) { 
  75.                 System.out.print(pt.summary()); 
  76.                 if (++count % 5 == 0) { 
  77.                     System.out.println(); 
  78.                 } 
  79.             } 
  80.             System.out.println(); 
  81.             System.out.println(this + " Calling shutdownNow()"); 
  82.             exec.shutdownNow(); 
  83.         } 
  84.     } 
  85.  
  86. class PrioritizedTaskProducer implements Runnable { 
  87.     private Random random = new Random(47); 
  88.     private Queue<Runnable> queue; 
  89.     private ExecutorService exec
  90.  
  91.     public PrioritizedTaskProducer(Queue<Runnable> queue, ExecutorService exec) { 
  92.         this.queue = queue; 
  93.         this.exec = exec
  94.     } 
  95.  
  96.     @Override 
  97.     public void run() { 
  98.         for (int i = 0; i < 20; i++) { 
  99.             queue.add(new PrioritizedTask(random.nextInt(10))); // 往PriorityBlockingQueue中添加隨機優先級的任務 
  100.             Thread.yield(); 
  101.         } 
  102.         try { 
  103.             for (int i = 0; i < 10; i++) { 
  104.                 TimeUnit.MILLISECONDS.sleep(250); 
  105.                 queue.add(new PrioritizedTask(10)); // 往PriorityBlockingQueue中添加優先級為10的任務 
  106.             } 
  107.             for (int i = 0; i < 10; i++) { 
  108.                 queue.add(new PrioritizedTask(i));// 往PriorityBlockingQueue中添加優先級為1-10的任務 
  109.             } 
  110.             queue.add(new PrioritizedTask.EndSentinel(exec)); 
  111.         } catch (InterruptedException e) { 
  112.         } 
  113.         System.out.println("Finished PrioritizedTaskProducer"); 
  114.     } 
  115.  
  116. class PrioritizedTaskConsumer implements Runnable { 
  117.     private PriorityBlockingQueue<Runnable> queue; 
  118.  
  119.     public PrioritizedTaskConsumer(PriorityBlockingQueue<Runnable> queue) { 
  120.         this.queue = queue; 
  121.     } 
  122.  
  123.     @Override 
  124.     public void run() { 
  125.         try { 
  126.             while (!Thread.interrupted()) { 
  127.                 queue.take().run(); // 任務的消費者,從PriorityBlockingQueue中取出任務執行 
  128.             } 
  129.         } catch (InterruptedException e) { 
  130.         } 
  131.         System.out.println("Finished PrioritizedTaskConsumer"); 
  132.     } 

 工作原理

PriorityBlockingQueue 是 JDK1.5 的時候出來的一個阻塞隊列。但是該隊列入隊的時候是不會阻塞的,永遠會加到隊尾。下面我們介紹下它的幾個特點:

  • PriorityBlockingQueue 和 ArrayBlockingQueue 一樣是基于數組實現的,但后者在初始化時需要指定長度,前者默認長度是 11。
  • 該隊列可以說是真正的無界隊列,它在隊列滿的時候會進行擴容,而前面說的無界阻塞隊列其實都有有界,只是界限太大可以忽略(最大值是 2147483647)
  • 該隊列屬于權重隊列,可以理解為它可以進行排序,但是排序不是從小到大排或從大到小排,是基于數組的堆結構(具體如何排下面會進行分析)
  • 出隊方式和前面的也不同,是根據權重來進行出隊,和前面所說隊列中那種先進先出或者先進后出方式不同。
  • 其存入的元素必須實現Comparator,或者在創建隊列的時候自定義Comparator。

注意:

  1. 堆結構實際上是一種完全二叉樹。關于二叉樹可以查看 《樹、二叉樹、二叉搜索樹的實現和特性》
  2. 堆又分為大頂堆和小頂堆 。大頂堆中第一個元素肯定是所有元素中最大的,小頂堆中第一個元素是所有元素中最小的。關于二叉堆可以查看《堆和二叉堆的實現和特性》

源碼分析

定義

PriorityBlockingQueue的類繼承關系如下:

其包含的方法定義如下:

成員屬性

從下面的字段我們可以知道,該隊列可以排序,使用顯示鎖來保證操作的原子性,在空隊列時,出隊線程會堵塞等。 

  1. /** 
  2. * 默認數組長度 
  3. */ 
  4. private static final int DEFAULT_INITIAL_CAPACITY = 11; 
  5.  
  6. /** 
  7.  * 最大達容量,分配時超出可能會出現 OutOfMemoryError 異常 
  8.  */ 
  9. private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; 
  10.  
  11. /** 
  12.  * 隊列,存儲我們的元素 
  13.  */ 
  14. private transient Object[] queue; 
  15.  
  16. /** 
  17.  * 隊列長度 
  18.  */ 
  19. private transient int size
  20.  
  21. /** 
  22.  * 比較器,入隊進行權重的比較 
  23.  */ 
  24. private transient Comparator<? super E> comparator; 
  25.  
  26. /** 
  27.  * 顯示鎖 
  28.  */ 
  29. private final ReentrantLock lock; 
  30.  
  31. /** 
  32.  * 空隊列時進行線程阻塞的 Condition 對象 
  33.  */ 
  34. private final Condition notEmpty; 

 構造函數 

  1. /** 
  2. * 默認構造,使用長度為 11 的數組,比較器為空 
  3. */ 
  4. public PriorityBlockingQueue() { 
  5.     this(DEFAULT_INITIAL_CAPACITY, null); 
  6. /** 
  7. * 自定義數據長度構造,比較器為空 
  8. */ 
  9. public PriorityBlockingQueue(int initialCapacity) { 
  10.     this(initialCapacity, null); 
  11. /** 
  12. * 自定義數組長度,可以自定義比較器 
  13. */ 
  14. public PriorityBlockingQueue(int initialCapacity, 
  15.                              Comparator<? super E> comparator) { 
  16.     if (initialCapacity < 1) 
  17.         throw new IllegalArgumentException(); 
  18.     this.lock = new ReentrantLock(); 
  19.     this.notEmpty = lock.newCondition(); 
  20.     this.comparator = comparator; 
  21.     this.queue = new Object[initialCapacity]; 
  22. /** 
  23. * 構造函數,帶有初始內容的隊列 
  24. */ 
  25. public PriorityBlockingQueue(Collection<? extends E> c) { 
  26.     this.lock = new ReentrantLock(); 
  27.     this.notEmpty = lock.newCondition(); 
  28.     boolean heapify = true; // true if not known to be in heap order 
  29.     boolean screen = true;  // true if must screen for nulls 
  30.     if (c instanceof SortedSet<?>) { 
  31.         SortedSet<? extends E> ss = (SortedSet<? extends E>) c; 
  32.         this.comparator = (Comparator<? super E>) ss.comparator(); 
  33.         heapify = false
  34.     } 
  35.     else if (c instanceof PriorityBlockingQueue<?>) { 
  36.         PriorityBlockingQueue<? extends E> pq = 
  37.             (PriorityBlockingQueue<? extends E>) c; 
  38.         this.comparator = (Comparator<? super E>) pq.comparator(); 
  39.         screen = false
  40.         if (pq.getClass() == PriorityBlockingQueue.class) // exact match 
  41.             heapify = false
  42.     } 
  43.     Object[] a = c.toArray(); 
  44.     int n = a.length; 
  45.     // If c.toArray incorrectly doesn't return Object[], copy it. 
  46.     if (a.getClass() != Object[].class) 
  47.         a = Arrays.copyOf(a, n, Object[].class); 
  48.     if (screen && (n == 1 || this.comparator != null)) { 
  49.         for (int i = 0; i < n; ++i) 
  50.             if (a[i] == null
  51.                 throw new NullPointerException(); 
  52.     } 
  53.     this.queue = a; 
  54.     this.size = n; 
  55.     if (heapify) 
  56.         heapify(); 

 入隊方法

入隊方法,下面可以看到 put 方法最終會調用 offer 方法,所以我們只看 offer 方法即可。

offer(E e)

  1. public void put(E e) { 
  2.     offer(e); // never need to block 
  3.  
  4. public boolean offer(E e) { 
  5.     //判斷是否為空 
  6.     if (e == null
  7.         throw new NullPointerException(); 
  8.     //顯示鎖 
  9.     final ReentrantLock lock = this.lock; 
  10.     lock.lock(); 
  11.     //定義臨時對象 
  12.     int n, cap; 
  13.     Object[] array; 
  14.     //判斷數組是否滿了 
  15.     while ((n = size) >= (cap = (array = queue).length)) 
  16.         //數組擴容 
  17.         tryGrow(array, cap); 
  18.     try { 
  19.         //拿到比較器 
  20.         Comparator<? super E> cmp = comparator; 
  21.         //判斷是否有自定義比較器 
  22.         if (cmp == null
  23.             //堆上浮 
  24.             siftUpComparable(n, e, array); 
  25.         else 
  26.             //使用自定義比較器進行堆上浮 
  27.             siftUpUsingComparator(n, e, array, cmp); 
  28.         //隊列長度 +1 
  29.         size = n + 1; 
  30.         //喚醒休眠的出隊線程 
  31.         notEmpty.signal(); 
  32.     } finally { 
  33.         //釋放鎖 
  34.         lock.unlock(); 
  35.     } 
  36.     return true

 siftUpComparable(int k, T x, Object[] array)

上浮調整比較器方法的實現

  1. private static <T> void siftUpComparable(int k, T x, Object[] array) { 
  2.         Comparable<? super T> key = (Comparable<? super T>) x; 
  3.         while (k > 0) { 
  4.          //無符號向左移,目的是找到放入位置的父節點 
  5.             int parent = (k - 1) >>> 1; 
  6.             //拿到父節點的值 
  7.             Object e = array[parent]; 
  8.             //比較是否大于該元素,不大于就沒比較交換 
  9.             if (key.compareTo((T) e) >= 0) 
  10.                 break; 
  11.             //以下都是元素位置交換 
  12.             array[k] = e; 
  13.             k = parent; 
  14.         } 
  15.         array[k] = key
  16.     } 

 根據上面的代碼,可以看出這是完全二叉樹在進行上浮調整。調整入隊的元素,找出最小的,將元素排列有序化。簡單理解就是:父節點元素值一定要比它的子節點得小,如果父節點大于子節點了,那就兩者位置進行交換。

入隊圖解

例子:85 添加到二叉堆中(大頂堆)

  1. package com.niuh.queue.priority; 
  2.  
  3. import java.util.Comparator; 
  4. import java.util.concurrent.PriorityBlockingQueue; 
  5.  
  6. /** 
  7.  * <p> 
  8.  * PriorityBlockingQueue 簡單演示 demo 
  9.  * </p> 
  10.  */ 
  11. public class TestPriorityBlockingQueue { 
  12.  
  13.     public static void main(String[] args) throws InterruptedException { 
  14.         // 大頂堆 
  15.         PriorityBlockingQueue<Integer> concurrentLinkedQueue = new PriorityBlockingQueue<Integer>(10, new Comparator<Integer>() { 
  16.             @Override 
  17.             public int compare(Integer o1, Integer o2) { 
  18.                 return o2 - o1; 
  19.             } 
  20.         }); 
  21.  
  22.         concurrentLinkedQueue.offer(90); 
  23.         concurrentLinkedQueue.offer(80); 
  24.         concurrentLinkedQueue.offer(70); 
  25.         concurrentLinkedQueue.offer(60); 
  26.         concurrentLinkedQueue.offer(40); 
  27.         concurrentLinkedQueue.offer(30); 
  28.         concurrentLinkedQueue.offer(20); 
  29.         concurrentLinkedQueue.offer(10); 
  30.         concurrentLinkedQueue.offer(50); 
  31.         concurrentLinkedQueue.offer(85); 
  32.         //輸出元素排列 
  33.         concurrentLinkedQueue.stream().forEach(e-> System.out.print(e+"  ")); 
  34.         //取出元素 
  35.         Integer take = concurrentLinkedQueue.take(); 
  36.         System.out.println(); 
  37.         concurrentLinkedQueue.stream().forEach(e-> System.out.print(e+"  ")); 
  38.     } 

 

操作的細節分為兩步:

  • 第一步:首先把新元素插入到堆的尾部再說;(新的元素可能是特別大或者特別小,那么要做的一件事情就是重新維護一下堆的所有元素,把新元素挪到這個堆的相應的位置)
  • 第二步:依次向上調整整個堆的結構,就叫 HeapifyUp

  

 85 按照上面講的先插入到堆的尾部,也就是一維數組的尾部,一維數組的尾部的話就上圖的位置,因為這是一個完全二叉樹,所以它的尾部就是50后面這個結點。插進來之后這個時候就破壞了堆,它的每一個結點都要大于它的兒子的這種屬性了,接下來要做的事情就是要把 85 依次地向上浮動,怎么浮動?就是 85 大于它的父親結點,那么就和父親結點進行交換,直到走到根如果大于根的話,就和根也進行交換。


85 再繼續往前走之后,它要和 80 再進行比較,同理可得:也就是說這個結點每次和它的父親比,如果它大于它的父親的話就交換,直到它不再大于它的父親。

 

出隊方法

入隊列的方法說完后,我們來說說出隊列的方法。PriorityBlockingQueue提供了多種出隊操作的實現來滿足不同情況下的需求,如下:

  • E take();
  • E poll();
  • E poll(long timeout, TimeUnit unit);
  • E peek()

poll 和 peek 與上面類似,這里不做說明

take()

出隊方法,該方法會阻塞

  1. public E take() throws InterruptedException { 
  2.  //顯示鎖 
  3.     final ReentrantLock lock = this.lock; 
  4.     //可中斷鎖 
  5.     lock.lockInterruptibly(); 
  6.     //結果接收對象 
  7.     E result; 
  8.     try { 
  9.      //判斷隊列是否為空 
  10.         while ( (result = dequeue()) == null
  11.          //線程阻塞 
  12.             notEmpty.await(); 
  13.     } finally { 
  14.         lock.unlock(); 
  15.     } 
  16.     return result; 

 dequeue()

我們再來看看具體出隊方法的實現,dequeue方法

  1. private E dequeue() { 
  2. //長度減少 1 
  3.    int n = size - 1; 
  4.    //判斷隊列中是否有元素 
  5.    if (n < 0) 
  6.        return null
  7.    else { 
  8.     //隊列對象 
  9.        Object[] array = queue; 
  10.        //取出第一個元素 
  11.        E result = (E) array[0]; 
  12.        //拿出最后一個元素 
  13.        E x = (E) array[n]; 
  14.        //置空 
  15.        array[n] = null
  16.        Comparator<? super E> cmp = comparator; 
  17.        if (cmp == null
  18.         //下沉調整 
  19.            siftDownComparable(0, x, array, n); 
  20.        else 
  21.            siftDownUsingComparator(0, x, array, n, cmp); 
  22.        //成功則減少隊列中的元素數量 
  23.        size = n; 
  24.        return result; 
  25.    } 

 總體就是找到父節點與兩個子節點中最小的一個節點,然后進行交換位置,不斷重復,由上而下的交換。

siftDownComparable(int k, T x, Object[] array, int n)

再來看看下沉比較器方法的實現

  1. private static <T> void siftDownComparable(int k, T x, Object[] array, 
  2.                                                int n) { 
  3.     //判斷隊列長度 
  4.     if (n > 0) { 
  5.         Comparable<? super T> key = (Comparable<? super T>)x; 
  6.         //找到隊列最后一個元素的父節點的索引。 
  7.         int half = n >>> 1;           // loop while a non-leaf 
  8.         while (k < half) { 
  9.          //拿到 k 節點下的左子節點 
  10.             int child = (k << 1) + 1; // assume left child is least 
  11.             //取得子節點對應的值 
  12.             Object c = array[child]; 
  13.             //取得 k 右子節點的索引 
  14.             int right = child + 1; 
  15.             //比較右節點的索引是否小于隊列長度和左右子節點的值進行比較 
  16.             if (right < n && 
  17.                 ((Comparable<? super T>) c).compareTo((T) array[right]) > 0) 
  18.                 c = array[child = right]; 
  19.             //比較父節點值是否大于子節點 
  20.             if (key.compareTo((T) c) <= 0) 
  21.                 break; 
  22.             //下面都是元素替換 
  23.             array[k] = c; 
  24.             k = child; 
  25.         } 
  26.         array[k] = key
  27.     } 

 出隊圖解

將堆尾元素替換到頂部(即堆頂被替代刪除掉)

依次從根部向下調整整個堆的結構(一直到堆尾即可) HeapifyDown

例子:90 從二叉堆中刪除(大頂堆)


總結

PriorityBlockingQueue 真的是個神奇的隊列,可以實現優先出隊。最特別的是它只有一個鎖,入隊操作永遠成功,而出隊只有在空隊列的時候才會進行線程阻塞。可以說有一定的應用場景吧,比如:有任務要執行,可以對任務加一個優先級的權重,這樣隊列會識別出來,對該任務優先進行出隊。

 

責任編輯:姜華 來源: 今日頭條
相關推薦

2020-11-19 07:41:51

ArrayBlocki

2020-11-25 14:28:56

DelayedWork

2020-11-20 06:22:02

LinkedBlock

2017-04-12 10:02:21

Java阻塞隊列原理分析

2025-01-14 00:00:00

Blocking隊列元素

2023-12-28 07:49:11

線程池源碼應用場景

2012-06-14 10:34:40

Java阻塞搜索實例

2023-12-15 09:45:21

阻塞接口

2025-04-02 01:20:00

阻塞隊列源碼

2022-06-30 08:14:05

Java阻塞隊列

2021-06-04 14:15:10

鴻蒙HarmonyOS應用

2024-10-14 12:34:08

2014-08-26 11:11:57

AsyncHttpCl源碼分析

2011-03-15 11:33:18

iptables

2024-02-20 08:16:10

阻塞隊列源碼

2021-09-22 14:36:32

鴻蒙HarmonyOS應用

2023-12-05 13:46:09

解密協程線程隊列

2011-05-26 10:05:48

MongoDB

2021-05-12 09:45:20

鴻蒙HarmonyOS應用

2021-11-11 17:40:08

WatchdogAndroid源碼分析
點贊
收藏

51CTO技術棧公眾號

欧美大胆性生话| 成人国产精品日本在线| 国产精品国产一区二区| 欧美性xxxx图片| 一级黄色片在线看| ccyy激情综合| 国产欧美视频一区二区| 欧美极品欧美精品欧美视频| 国产又大又黄又粗的视频| 亚洲国产精品久久久久久久| av亚洲免费| 狠狠色狠色综合曰曰| 91精品国产99久久久久久红楼| 91精品人妻一区二区| 青草av在线| 欧美激情偷拍自拍| 日韩人体视频一二区| 99在线影院| 97在线观看免费高| 免费成人黄色网| 久久久91精品国产一区二区精品 | 日韩av一区二区三区四区| 欧美日韩中文一区| 免费av一区二区三区| 久久久久久久久久久97| 欧洲午夜精品| 中文字幕一区二区三区四区不卡| 欧美中文字幕视频| 特级西西人体4444xxxx| www在线观看黄色| 成人一道本在线| 久久99久久亚洲国产| 五月天婷婷影视| 欧美被日视频| 国产一二三精品| 久久久国产精彩视频美女艺术照福利 | 亚洲精品欧美二区三区中文字幕| 欧美第一页在线| 无码人妻一区二区三区精品视频| 麻豆91在线| 国产欧美一区视频| 久久国产一区二区| 欧美一区免费看| 国产精品亚洲片在线播放| 色婷婷精品大在线视频| 国产无限制自拍| 亚洲色图 校园春色| 久久aⅴ国产紧身牛仔裤| 日韩高清有码在线| 乱子伦视频在线看| av在线免费观看网| 国产一区二区三区观看| 国产精品青草久久久久福利99| 黄大色黄女片18免费| 日韩五码电影| 欧美日韩精品综合在线| 一本大道东京热无码aⅴ| 亚洲精品喷潮一区二区三区| 国产精品一级片在线观看| 91精品国产色综合久久不卡98口| wwwwxxxx国产| 小说区图片区亚洲| 欧美日韩亚洲综合一区| 色国产在线视频| 久久亚洲资源| 亚洲sss视频在线视频| 日韩中文字幕一区二区| 99久久久国产精品无码网爆| 亚洲成人直播| 国产一区二区三区精品久久久| 国产欧美精品一二三| 蜜臀久久精品| 亚洲久本草在线中文字幕| 可以在线看黄的网站| 完全免费av在线播放| 99久久精品国产导航| 国产精品久久77777| 久久久久久久久久久网| 亚洲精品少妇| 久久深夜福利免费观看| 黄色网址在线视频| 亚洲精品蜜桃乱晃| 日韩欧美aaaaaa| 男女曰b免费视频| 精品123区| 午夜精品久久久久久久99水蜜桃| 激情伊人五月天| 免费黄色网页在线观看| 夜夜嗨av一区二区三区| 亚洲一区不卡在线| 飘雪影院手机免费高清版在线观看 | 国模精品视频一区二区三区| jizz中文字幕| 国产一区二区在线视频你懂的| 欧美性生活影院| 777精品久无码人妻蜜桃| 国产素人视频在线观看| 国产精品无人区| 免费看污久久久| 麻豆传媒在线观看| 午夜精品视频一区| 中文字幕成人在线视频| 丁香一区二区| 色偷偷88888欧美精品久久久 | 亚洲国产精品成人综合 | 亚洲人体大胆视频| 国产日韩在线播放| 在线视频精品免费| 久久精选视频| 97伦理在线四区| jzzjzzjzz亚洲成熟少妇| 亚洲国产aⅴ天堂久久| 黄色三级中文字幕| 午夜在线激情影院| 亚洲欧美在线aaa| 亚洲精品乱码视频| 天堂аⅴ在线地址8| 国产精品久久久久久久久图文区| www.日本少妇| av影院在线免费观看| 亚洲444eee在线观看| 在线观看免费的av| 日韩成人动漫| 亚洲成年人在线| 国产美女喷水视频| 欧美1区2区| 欧美激情综合亚洲一二区| 人体内射精一区二区三区| 最新日韩免费视频| 国产成人精品一区二区免费看京| 久久艳片www.17c.com| 一级一片免费看| 99久久精品情趣| 欧美久久久久久久| 成人18在线| 午夜精品久久久久久不卡8050| 岛国大片在线免费观看| 国产精品久av福利在线观看| 久久影院资源网| 亚洲一区 中文字幕| 九一久久久久久| 97久久人人超碰caoprom欧美| 最新真实国产在线视频| 亚洲免费在线看| 午夜免费看视频| 久久久影院免费| 国产欧美一区二区| 午夜伦理在线| 欧美精品一级二级三级| 亚洲五月激情网| 香蕉视频官网在线观看日本一区二区| 九九热精品视频国产| 国产精品欧美久久久久天天影视| 国产白丝网站精品污在线入口| 国产偷国产偷亚洲高清97cao| 邻家有女韩剧在线观看国语| 亚洲天堂免费看| 内射国产内射夫妻免费频道| 日韩激情网站| 久久夜色精品亚洲噜噜国产mv | 日韩天堂av| 国产女主播视频一区二区| 老司机午夜免费福利视频| 久久久久毛片免费观看| 日韩精品免费在线| 五月天婷婷久久| 久久99国产精品久久99| 伊人精品久久久久7777| 超碰资源在线| 亚洲美女性生活视频| 国产精品成人免费观看| 午夜亚洲伦理| 成人欧美一区二区三区视频| 狠狠色伊人亚洲综合网站l| 亚洲精品国产无套在线观| 中文字幕18页| 欧美一区=区| 宅男av一区二区三区| 久久综合偷偷噜噜噜色| 高清欧美电影在线| 可以直接在线观看的av| 欧美区一区二区三区| 欧美色图一区二区| 91丝袜国产在线播放| 水蜜桃在线免费观看| 福利片一区二区| 国产a∨精品一区二区三区不卡| 亚洲卡一卡二卡三| 欧美性猛交xxxx富婆弯腰| 久久国产免费视频| 国产精品不卡| 国产精品欧美日韩久久| 黄色国产网站在线播放| 亚洲精品国产suv| 欧美爱爱小视频| 久久夜色精品国产噜噜av| 妺妺窝人体色www看人体| 日韩大片在线免费观看| 成人精品一区二区三区| 亚洲美女炮图| 亚洲国产精品成人av| 国产亚洲久一区二区| 久久久久久免费| 国产资源中文字幕| 欧美在线免费| 日本一区二区久久精品| 456亚洲精品成人影院| 国产视频精品免费播放| 国产成人免费观看视频 | 国产精品中文字幕在线| 欧美伦理影视网| 日韩三级免费观看| 欧美成人精品欧美一级| 国产日本亚洲高清| 欧美视频免费播放| 色综合中文网| 国产精品久久久久久久电影| 丁香花在线影院| 韩国美女久久| 日韩欧美999| 五月天激情丁香| 精品系列免费在线观看| 一区二区三区四区国产| 任你弄精品视频免费观看| 91sao在线观看国产| 最新黄网在线观看| 精品国产百合女同互慰| 国产在线免费视频| a美女胸又www黄视频久久| 国产精欧美一区二区三区白种人| 视频一区二区三区入口| 亚洲欧洲精品一区二区三区波多野1战4| 国产suv精品一区| 91精品网站| 精品三级国产| 成人在线国产精品| 日本国产亚洲| 国产男女猛烈无遮挡91| 播放一区二区| 国产成人a亚洲精品| av中文在线| 在线播放精品一区二区三区| 91一区二区视频| 欧美三级日韩三级| 丰满人妻一区二区三区四区| 色婷婷久久99综合精品jk白丝 | 国内自拍一区| 久久国产精品亚洲va麻豆| 成人爽a毛片免费啪啪红桃视频| av在线不卡观看| jazzjazz国产精品麻豆| 高清视频一区二区三区| 草草视频在线一区二区| 国产三区精品| 偷拍视屏一区| 日韩资源av在线| 亚洲调教欧美在线| 国产精品老牛| 先锋影音一区二区三区| 成人羞羞网站入口| 成人综合电影| 久9re热视频这里只有精品| 国产精品久久久久国产a级| 免费观看成人性生生活片| 国产精品三级久久久久久电影| 国产精品99精品一区二区三区∴| 欧美激情一区二区三区久久久| 国产蜜臀在线| 2019精品视频| 黄色免费在线网站| 久久久精品免费视频| 色婷婷视频在线观看| 国外成人在线直播| 欧美香蕉视频| 成人免费网站在线观看| 成人精品动漫一区二区三区| 欧美国产综合视频| 国产精品99久久| 国产妇女馒头高清泬20p多| 麻豆精品91| 亚洲一区二区三区观看| 成人av资源站| 尤物网站在线看| 成人av片在线观看| 微拍福利一区二区| 亚洲美女在线一区| 日韩精品在线免费视频| 亚洲一区国产视频| 国产成人av免费在线观看| 亚洲综合男人的天堂| 日韩手机在线视频| 午夜天堂影视香蕉久久| 亚洲天堂男人av| 日本一区高清| 亚洲精品一区二区三区香蕉| 国产视频精选在线| 日韩精品免费在线视频| wwwww在线观看免费视频| 欧美高清视频在线播放| 欧洲精品一区二区三区| 不卡视频一区二区| 日韩欧美在线中字| 日韩高清在线播放| 永久亚洲成a人片777777| 亚洲图片欧洲图片日韩av| 午夜天堂精品久久久久| 国产一区二区视频免费在线观看 | 国产精品成人免费电影| 国产一区二区在线观| 国产日产欧美a一级在线| 乱亲女h秽乱长久久久| 91xxx视频| 欧美激情第10页| 粉嫩虎白女毛片人体| 丁香一区二区三区| 伊人久久久久久久久久久久久久| 国产精品乱人伦| 激情五月深爱五月| 欧美日韩色婷婷| 精品国产伦一区二区三区| 7777精品伊人久久久大香线蕉的 | 精品一区二区三区视频在线观看| wwwwww日本| 欧美日韩一区二区在线 | 久久久综合九色合综国产精品| 久久久久99精品成人片试看| 欧美蜜桃一区二区三区| 番号集在线观看| 欧美最猛性xxxxx(亚洲精品)| 超碰97成人| 成人免费看片'免费看| 国产黄色精品网站| 中文字幕永久免费| 亚洲欧洲成人av每日更新| 天天天天天天天干| 亚洲欧美在线x视频| 精品av中文字幕在线毛片| 久久琪琪电影院| 高清精品xnxxcom| www.欧美黄色| 懂色av一区二区夜夜嗨| 国产麻豆视频在线观看| 欧美另类变人与禽xxxxx| 在线观看免费版| 国产精品一区专区欧美日韩| 日韩毛片视频| 国产福利精品一区二区三区| 亚洲欧美一区二区三区久本道91| 国产精品伦理一区| 久久综合久久美利坚合众国| 奇米一区二区| 欧美日韩国产一二| 蜜桃久久av| 中文字幕免费在线看线人动作大片| 91国产免费看| 成人午夜免费在线观看| 亚洲人成电影在线观看天堂色| 亚洲妇女成熟| 日韩免费av电影| 久久av中文字幕片| 国产成人无码aa精品一区| 日韩精品一区二| 九色porny自拍视频在线观看| 蜜桃麻豆www久久国产精品| 久久久久一区| 欧美日韩国产一二三区| 日韩午夜激情视频| 国产高清自产拍av在线| 欧美精品尤物在线| 麻豆精品新av中文字幕| 在线观看免费视频黄| 国产精品国产三级国产有无不卡 | av 日韩 人妻 黑人 综合 无码| 国产成人鲁色资源国产91色综| 亚洲国产精一区二区三区性色| 欧美日韩激情一区二区三区| 黄视频网站在线| 国产一区免费视频| 日韩精品免费视频人成| 久久久午夜精品福利内容| 中文字幕一区二区三区不卡在线| av免费观看在线| 中文字幕亚洲欧美日韩高清| 精品国产免费人成网站| 亚洲精品日韩成人| 国产精品99久久久| 永久免费无码av网站在线观看| 自拍亚洲一区欧美另类| 理论片一区二区在线| 在线观看岛国av| 粉嫩av一区二区三区免费野| 95在线视频| 久久久久天天天天| 国产综合久久久久影院| 亚洲日本视频在线观看| 三级精品视频久久久久| 欧美aaaaa级| 国产无色aaa| 欧美日韩中文字幕在线视频| av在线播放国产|