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

java使用默認線程池踩過的坑

網絡 網絡管理 網絡運維
直接使用java默認的線程池調度task1和task2.由于外部txt的種種不可控原因,導致task2線程阻塞?,F象就是task1和線程池調度器都正常運行著,但是task2遲遲沒有動作。我們需要保證任務線程或者調度器的健壯性!

場景

一個調度器,兩個調度任務,分別處理兩個目錄下的txt文件,某個調度任務應對某些復雜問題的時候會持續特別長的時間,甚至有一直阻塞的可能。我們需要一個manager來管理這些task,當這個task的上一次執行時間距離現在超過5個調度周期的時候,就直接停掉這個線程,然后再重啟它,保證兩個目標目錄下沒有待處理的txt文件堆積。

java使用默認線程池踩過的坑

問題

直接使用java默認的線程池調度task1和task2.由于外部txt的種種不可控原因,導致task2線程阻塞?,F象就是task1和線程池調度器都正常運行著,但是task2遲遲沒有動作。

當然,找到具體的阻塞原因并進行針對性解決是很重要的。但是,這種措施很可能并不能完全、徹底、全面的處理好所有未知情況。我們需要保證任務線程或者調度器的健壯性!

方案計劃

線程池調度器并沒有原生的針對被調度線程的業務運行狀態進行監控處理的API。因為task2是阻塞在我們的業務邏輯里的,所以***的方式是寫一個TaskManager,所有的任務線程在執行任務前全部到這個TaskManager這里來注冊自己。這個TaskManager就負責對于每個自己管轄范圍內的task進行實時全程監控!

java使用默認線程池踩過的坑

后面的重點就是如何處理超過5個執行周期的task了。

方案如下:

●一旦發現這個task線程,立即中止它,然后再次重啟;

一旦發現這個task線程,直接將整個pool清空并停止,重新放入這兩個task ——【task明確的情況下】;

方案實施

中止后重啟

Task實現類

  1. class FileTask extends Thread { 
  2. private long lastExecTime = 0
  3. protected long interval = 10000
  4. public long getLastExecTime() { 
  5.     return lastExecTime; 
  6. public void setLastExecTime(long lastExecTime) { 
  7.     this.lastExecTime = lastExecTime; 
  8. public long getInterval() { 
  9.     return interval; 
  10. public void setInterval(long interval) { 
  11.     this.interval = interval; 
  12. }  
  13. public File[] getFiles() { 
  14.     return null; 

Override

  1. public void run() { 
  2. while (!Thread.currentThread().isInterrupted()) { 
  3. lastExecTime = System.currentTimeMillis(); 
  4. System.out.println(Thread.currentThread().getName() + " is running -> " + new Date()); 
  5. try { 
  6. Thread.sleep(getInterval() * 6 * 1000); 
  7. } catch (InterruptedException e) { 
  8. Thread.currentThread().interrupt(); 
  9. e.printStackTrace();    // 當線程池shutdown之后,這里就會拋出exception了 
  10.             } 
  11.         } 
  12.     } 
  13.     

TaskManager

  1. public class TaskManager  implements Runnable { 
  2. private final static Log logger = LogFactory.getLog(TaskManager .class); 
  3. public Set<FileTask> runners = new CopyOnWriteArraySet<FileTask>(); 
  4. ExecutorService pool = Executors.newCachedThreadPool(); 
  5. public void registerCodeRunnable(FileTask process) { 
  6. runners.add(process); 
  7. public TaskManager (Set<FileTask> runners) { 
  8. this.runners = runners; 

@Override

  1. public void run() { 
  2.        while (!Thread.currentThread().isInterrupted()) { 
  3.            try { 
  4.                long current = System.currentTimeMillis(); 
  5.                for (FileTask wrapper : runners) { 
  6.                    if (current - wrapper.getLastExecTime() > wrapper.getInterval() * 5) { 
  7.                        wrapper.interrupt(); 
  8.                        for (File file : wrapper.getFiles()) { 
  9.                            file.delete(); 
  10.                        } 
  11.                     wrapper.start();   
  12.                    } 
  13.                } 
  14.            } catch (Exception e1) { 
  15.                logger.error("Error happens when we trying to interrupt and restart a task "); 
  16.                ExceptionCollector.registerException(e1); 
  17.            } 
  18.            try { 
  19.                Thread.sleep(500); 
  20.            } catch (InterruptedException e) { 
  21.            } 
  22.        } 
  23.    } 
  24.     

這段代碼會報錯 java.lang.Thread IllegalThreadStateException。為什么呢?其實這是一個很基礎的問題,您應該不會像我一樣馬虎。查看Thread.start()的注釋, 有這樣一段:

It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.

是的,一個線程不能夠啟動兩次。那么它是怎么判斷的呢?

  1. public synchronized void start() { 
  2.         /** 
  3.          * A zero status value corresponds to state "NEW".    0對應的是state NEW 
  4.          */ 

if (threadStatus != 0) //如果不是NEW state,就直接拋出異常!#p#

  1. throw new IllegalThreadStateException(); 
  2.         group.add(this); 
  3.         boolean started = false
  4.         try { 
  5.         start0();    // 啟動線程的native方法 
  6.         started = true
  7.         } finally { 
  8.             try { 
  9.                 if (!started) { 
  10.                     group.threadStartFailed(this); 
  11.                 } 
  12.             } catch (Throwable ignore) { 
  13.             } 
  14.         } 
  15.     } 

恩,只有是NEW狀態才能夠調用native方法啟動一個線程。好吧,到這里了,就普及也自補一下jvm里的線程狀態:

所有的線程狀態::

NEW —— 還沒有啟動過

RUNNABLE —— 正在jvm上運行著

BLOCKED —— 正在等待鎖/信號量被釋放

WAITING —— 等待其他某個線程的某個特定動作

TIMED_WAITING —— A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.

TERMINATED —— 退出,停止

線程在某個時間點上只可能存在一種狀態,這些狀態是jvm里的,并不反映操作系統線程的狀態。查一下Thread的API,沒有對其狀態進行修改的API。那么這條路是不通的嗎?

仔細考慮一下……

如果把任務做成Runnable實現類,然后在把這個實現類丟進線程池調度器之前,利用此Runnable構造一個Thread,是不是這個Thread對象就能夠控制這個runnable對象,進而控制在線程池中運行著的task了呢?非也!讓我們看看Thread和ThreadPoolExecutor對Runnable的處理吧。

Thread

  1. /* What will be run. */ 
  2. private Runnable target; 

 

結合上面的start()方法,很容易猜出,start0()會把target弄成一個線程來進行運行。

ThreadPoolExecutor

  1. public void execute(Runnable command) { 
  2.         if (command == null) 
  3.             throw new NullPointerException(); 
  4.         int c = ctl.get(); 
  5.         if (workerCountOf(c) < corePoolSize) { 
  6.             if (addWorker(command, true)) 
  7.                 return; 
  8.             c = ctl.get(); 
  9.         } 
  10.         if (isRunning(c) && workQueue.offer(command)) { 
  11.             int recheck = ctl.get(); 
  12.             if (! isRunning(recheck) && remove(command)) 
  13.                 reject(command); 
  14.             else if (workerCountOf(recheck) == 0) 
  15.                 addWorker(null, false); 
  16.         } 
  17.         else if (!addWorker(command, false)) 
  18.             reject(command); 
  19. private boolean addWorker(Runnable firstTask, boolean core) { 
  20. … 
  21. boolean workerStarted = false
  22. boolean workerAdded = false
  23. Worker w = null
  24. try { 
  25. final ReentrantLock mainLock = this.mainLock; 
  26. w = new Worker(firstTask); 
  27. final Thread t = w.thread; 
  28. if (t != null) { 
  29. mainLock.lock(); 
  30. try { 
  31. int c = ctl.get(); 
  32. int rs = runStateOf(c); 
  33. if (rs < SHUTDOWN || 
  34. (rs == SHUTDOWN && firstTask == null)) { 
  35. if (t.isAlive()) // precheck that t is startable 
  36. throw new IllegalThreadStateException(); 
  37. workers.add(w); 
  38. int s = workers.size(); 
  39. if (s > largestPoolSize) 
  40. largestPoolSize = s; 
  41. workerAdded = true
  42. } finally { 
  43. mainLock.unlock(); 
  44. if (workerAdded) { 
  45. t.start(); 
  46. workerStarted = true
  47. } finally { 
  48. if (! workerStarted) 
  49. addWorkerFailed(w); 
  50. return workerStarted; 

那么Worker又是怎樣的呢?

Worker

  1. private final class Worker 
  2. extends AbstractQueuedSynchronizer 
  3. implements Runnable 
  4. final Thread thread; 
  5. Runnable firstTask; 
  6. volatile long completedTasks; 
  7. Worker(Runnable firstTask) { 
  8. setState(-1); //調用runWorker之前不可以interrupt 
  9. this.firstTask = firstTask; 
  10. this.thread = getThreadFactory().newThread(this); 
  11. public void run() { 
  12. runWorker(this); 
  13. ……   
  14. ……. 
  15. void interruptIfStarted() { 
  16. Thread t; 
  17. if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) { 
  18. try { 
  19. t.interrupt(); 
  20. } catch (SecurityException ignore) { 

可見worker里既包裝了Runnable對象——task,又包裝了一個Thread對象——以自己作為初始化參數,因為worker也是Runnable對象。然后對外提供了運行與停止接口,run()和interruptIfStarted()。回顧上面使用Thread的例子不禁有了新的領悟,我們把一個Thread對象交給ThreadPoolExecutor執行后,實際的調用是對Thread(FileTask())對象,我們暫時稱之為workerWrapper。那么我們在池外進行FileTask.interrupt()操作影響的是FileTask對象,而不是workerWrapper。所以可能上面對于start()方法二次調用不是特別適當。更恰當的應該是在fileTask.interrupt()的時候就跑出異常,因為從來沒有對fileTask對象執行過start()方法,這時候去interrupt就會出現錯誤。具體如下圖:

java使用默認線程池踩過的坑

分析到此,我們已經明確除了調用ThreadPoolExecutor了的interruptWorkers()方法別無其他途徑操作這些worker了。

  1. private void interruptWorkers() { 
  2. final ReentrantLock mainLock = this.mainLock; 
  3. mainLock.lock(); 
  4. try { 
  5. for (Worker w : workers) 
  6. w.interruptIfStarted(); 
  7. } finally { 
  8. mainLock.unlock(); 

重啟線程池

●TaskManager

  1. public class TaskManager  implements Runnable { 
  2. ….. 
  3. public TaskManager (Set<FileTask> runners) { 
  4. super(); 
  5. this.runners = runners; 
  6. executeTasks(runners); 
  7. private void executeTasks(Set<FileTask> runners) { 
  8. for (FileTask task : runners) { 
  9. pool.execute(task); 
  10. System.out.println(task.getClass().getSimpleName() + " has been started"); 

@Override

  1. public void run() { 
  2. while (!Thread.currentThread().isInterrupted()) { 
  3. try { 
  4. long current = System.currentTimeMillis(); 
  5. for (FileTask wrapper : runners) { 
  6. if (wrapper.getLastExecTime() != 0 && current - wrapper.getLastExecTime() > wrapper.getInterval() * 5 * 1000) {    // 開始忘了乘以1000 
  7. wrapper.interrupt(); 
  8. if (wrapper.getFiles() != null){ 
  9. for (File file : wrapper.getFiles()) { 
  10. file.delete(); 
  11. System.out.println("Going to shutdown the thread pool"); 
  12. List<Runnable> shutdownNow = pool.shutdownNow();    // 不等當前pool里的任務執行完,直接關閉線程池 
  13. for (Runnable run : shutdownNow) { 
  14. System.out.println(run + " going to be shutdown"); 
  15. while (pool.awaitTermination(1, TimeUnit.SECONDS)) {   
  16. System.out.println("The thread pool has been shutdown " + new Date()); 
  17. executeTasks(runners); // 重新執行 
  18. Thread.sleep(200); 
  19. } catch (Exception e1) { 
  20. e1.printStackTrace(); 
  21. try { 
  22. Thread.sleep(500); 
  23. } catch (InterruptedException e) { 
  24. public static void main(String[] args) { 
  25. Set<FileTask> tasks = new HashSet<FileTask>(); 
  26.         
  27. FileTask task = new FileTask(); 
  28. task.setInterval(1); 
  29. task.setName("task-1"); 
  30. tasks.add(task); 
  31.                
  32. FileTask task1 = new FileTask(); 
  33. task1.setInterval(2); 
  34. task.setName("task-2"); 
  35. tasks.add(task1); 
  36.         
  37. TaskManager  codeManager = new TaskManager (tasks); 
  38. new Thread(codeManager).start(); 
  39. }    

成功!把整個的ThreadPoolExector里所有的worker全部停止,之后再向其隊列里重新加入要執行的兩個task(注意這里并沒有清空,只是停止而已)。這樣做雖然能夠及時處理task,但是一個很致命的缺點在于,如果不能明確的知道ThreadPoolExecutor要執行的task,就沒有辦法重新執行這些任務。#p#

定制線程池

好吧!停止鉆研別人的東西!我們完全可以自己寫一個自己的ThreadPoolExecutor,只要把worker暴露出來就可以了。這里是不是回想起前面的start問題來了,沒錯,我們即便能夠直接針對Thread進行interrupt, 但是不能再次start它了。那么clone一個同樣的Thread行不行呢?#p#

Thread

  1. @Override 
  2. protected Object clone() throws CloneNotSupportedException { 
  3. throw new CloneNotSupportedException(); 

 

答案顯而易見,線程是不支持clone 的。我們需要重新new 一個Thread來重新運行。其實我們只需要將原來的Worker里的Runnable換成我們自己的task,然后將訪問權限適當放開就可以了。還有,就是讓我們的CustomThreadPoolExecutor繼承Thread,因為它需要定時監控自己的所有的worker里Thread的運行狀態。

CustomThreadPoolExecutor

  1. public class CustomThreadPoolExecutor extends ThreadPoolExecutor implements Runnable {  
  2. public void execute(Testask command) { 
  3. ….//將執行接口改為接收我們的業務類 
  4. … 
  5. … 
  6. private final class Worker 
  7. extends AbstractQueuedSynchronizer 
  8. implements Runnable 
  9. … 
  10. Testask firstTask; //將Runnable改為我們的業務類,方便查看狀態 
  11. … 
  12. Worker(Testask firstTask) { 
  13. …//同樣將初始化參數改為我們的業務類 
  14.  
  15. public static void main(String[] args) { 
  16. CustomThreadPoolExecutor pool = new CustomThreadPoolExecutor(0, Integer.MAX_VALUE, 
  17. 60L, TimeUnit.SECONDS, 
  18. new SynchronousQueue<Runnable>()); 
  19.          
  20. Testask task = new Testask(); 
  21. task.setInterval(1); 
  22. pool.execute(task); 
  23.          
  24. Testask task1 = new Testask(); 
  25. task1.setInterval(2); 
  26. pool.execute(task1); 
  27.          
  28. new Thread(pool).start(); 
  29.  
  30. @Override 
  31. public void run() { 
  32. while (!Thread.currentThread().isInterrupted()) { 
  33. try { 
  34. long current = System.currentTimeMillis(); 
  35. Set<Testask> toReExecute = new HashSet<Testask>(); 
  36. System.out.println("\t number is " + number); 
  37. for (Worker wrapper : workers) { 
  38. Testask tt = wrapper.firstTask; 
  39. if (tt != null) { 
  40. if (current - tt.getLastExecTime() > tt.getInterval() * 5 * 1000) { 
  41. wrapper.interruptIfStarted(); 
  42. remove(tt); 
  43. if (tt.getFiles() != null) { 
  44. for (File file : tt.getFiles()) { 
  45. file.delete(); 
  46. System.out.println("THread is timeout : " + tt + " " + new Date()); 
  47. toReExecute.add(tt); 
  48. if (toReExecute.size() > 0) { 
  49. mainLock.lock(); 
  50. try { 
  51. for (Testask tt : toReExecute) { 
  52. execute(tt);    // execute this task again 
  53. }  
  54. } finally { 
  55. mainLock.unlock(); 
  56. } catch (Exception e1) { 
  57. System.out.println("Error happens when we trying to interrupt and restart a code task "); 
  58. try { 
  59. Thread.sleep(500); 
  60. } catch (InterruptedException e) { 

Testask

  1. class Testask implements Runnable { 
  2. ….. 
  3.  
  4. @Override 
  5. public void run() { 
  6. while (!Thread.currentThread().isInterrupted()) { 
  7. lastExecTime = System.currentTimeMillis(); 
  8. System.out.println(Thread.currentThread().getName() + " is running -> " + new Date()); 
  9. try { 
  10. CustomThreadPoolExecutor.number++; 
  11. Thread.sleep(getInterval() * 6 * 1000); 
  12.                 System.out.println(Thread.currentThread().getName() + " after sleep"); 
  13. } catch (InterruptedException e) { 
  14. Thread.currentThread().interrupt(); 
  15. System.out.println("InterruptedException happens"); 
  16. System.out.println("Going to die"); 

最終方案

綜上,最穩妥的就是使用JDK自帶的ThreadPoolExecutor, 如果需要對池里的task進行任意時間的控制,可以考慮全面更新,全方面,360度無死角的定制自己的線程池當然是***的方案,但是一定要注意對于共享對象的處理,適當的處理好并發訪問共享對象的方法。

 

鑒于我們的場景,由于時間緊,而且需要了解的task并不多,暫時選用全部重新更新的策略。上線后,抽時間把自己定制的ThreadPoolExecutor搞定,然后更新上去!

 

責任編輯:守望幸福 來源: 51CTO.com
相關推薦

2017-07-17 15:46:20

Oracle并行機制

2024-02-04 08:26:38

線程池參數內存

2024-04-01 08:05:27

Go開發Java

2024-05-06 00:00:00

緩存高并發數據

2018-01-10 13:40:03

數據庫MySQL表設計

2019-10-30 14:44:41

Prometheus開源監控系統

2025-04-14 09:31:03

2025-04-29 10:17:42

2018-09-11 09:14:52

面試公司缺點

2023-03-13 13:36:00

Go擴容切片

2025-06-06 02:00:00

2020-11-03 13:50:31

Redis緩存數據庫

2024-12-13 08:21:04

2022-04-26 21:49:55

Spring事務數據庫

2018-01-10 06:17:24

2024-04-10 08:39:56

BigDecimal浮點數二進制

2025-07-08 09:09:32

MySQL類型

2019-12-12 14:32:26

SQL語句數據庫

2025-11-18 01:33:00

2025-10-16 08:10:59

點贊
收藏

51CTO技術棧公眾號

蜜桃av鲁一鲁一鲁一鲁俄罗斯的 | 成人在线免费在线观看| 天堂中文在线视频| 日韩欧美一中文字暮专区| 成人h动漫精品一区二| 日韩免费观看视频| 午夜剧场免费在线观看| 精品综合久久88少妇激情| 欧洲一区在线观看| 日韩小视频网站| av网站在线免费观看| 成人黄色网址在线观看| 国产精品久久77777| 久久久久久久极品内射| 国产一区二区三区四区| 91精品国产91久久久久久一区二区| 真人抽搐一进一出视频| 思思99re6国产在线播放| 亚洲影视综合| 久久精品国产一区二区电影| 亚洲欧美日韩偷拍| 四虎影视国产精品| 日韩欧美国产网站| 精品国产区在线| 91丨九色丨丰满| 免费亚洲视频| 午夜精品一区二区三区在线视| 国产成人精品视频免费| 色狠狠久久av综合| 精品美女一区二区三区| 午夜国产福利在线观看| 成人黄页网站视频| 日韩欧美aaa| 黄色国产一级视频| 在线观看xxx| 国产福利一区二区| 成人黄色激情网| а中文在线天堂| 免费精品视频| 欧美中文字幕视频| 国产成人免费看| 亚洲激情二区| 久久人人爽国产| 久久久精品人妻一区二区三区四| 欧美大片aaaa| 最近2019中文免费高清视频观看www99| 色噜噜在线观看| 噜噜噜狠狠夜夜躁精品仙踪林| 精品国产凹凸成av人导航| 国内av免费观看| 成人免费观看在线观看| 夜夜精品视频一区二区| 日本久久高清视频| 成人免费网站在线观看视频| 《视频一区视频二区| 中文字幕中文字幕在线中一区高清| 成年人在线观看视频| 久久久久国产精品人| 国产精品主播视频| 中文字幕乱码无码人妻系列蜜桃| 久久亚洲影院| 国产精品av网站| 超碰在线97观看| 久久精品国产精品亚洲综合| 国产中文字幕亚洲| a毛片在线免费观看| 高清在线成人网| 国内视频一区| 韩国三级av在线免费观看| 欧美韩国日本不卡| 在线观看日韩片| 性xxxxfjsxxxxx欧美| 亚洲一区国产视频| 久久久999视频| 电影一区电影二区| 亚洲一区二区三区视频在线播放| 国产一级大片免费看| av电影院在线看| 色综合中文字幕| 亚洲一区精品视频在线观看| 深夜福利一区| 亚洲欧美制服另类日韩| 中国老熟女重囗味hdxx| 在线一区视频观看| 欧美高清一级片在线| 中文字幕99页| 精品视频在线观看免费观看| 欧美不卡在线视频| 欧美特黄一区二区三区| 999久久久亚洲| 韩剧1988在线观看免费完整版| 亚洲毛片一区二区三区| 久久99精品久久久久久国产越南| 国产精品永久入口久久久| 免费在线高清av| 亚洲摸摸操操av| 少妇性l交大片| 亚洲精品在线国产| 国产亚洲一区精品| 国产无套粉嫩白浆内谢| 青青草国产精品亚洲专区无| 亚洲a中文字幕| 免费理论片在线观看播放老| 亚洲精品成人在线| 黄色一级二级三级| 爱爱精品视频| 久久久精品一区二区| 亚洲天堂av片| 国产不卡在线播放| 先锋影音网一区| 欧美三级网站| 日韩精品一区二区三区视频在线观看| 亚洲精品国产一区黑色丝袜| 国内揄拍国内精品久久| 欧美噜噜久久久xxx| 免费的毛片视频| 国产69精品久久久久777| 在线视频不卡一区二区| 爱情电影社保片一区| 精品国产麻豆免费人成网站| 日韩av片在线免费观看| 久久综合伊人| 精品毛片久久久久久| 18视频在线观看| 亚洲午夜一区二区| 伊人免费视频二| 中文字幕av一区二区三区四区| 国产午夜精品视频| 99久在线精品99re8热| 高清成人在线观看| 做爰高潮hd色即是空| 欧洲成人一区| 亚洲视频在线视频| av大全在线观看| av一区二区久久| 日韩欧美亚洲在线| 中文字幕乱码在线播放| 日韩av在线导航| 国产午夜激情视频| 不卡一区在线观看| 精品国偷自产一区二区三区| 欧美午夜在线播放| 久久国产精品影片| 国产肥老妇视频| 亚洲女厕所小便bbb| 初高中福利视频网站| 亚洲国产精品久久久天堂| 国产日韩一区在线| 免费**毛片在线| 欧美高清激情brazzers| 中文字幕求饶的少妇| 久久成人羞羞网站| 蜜桃视频成人在线观看| 日本免费一区二区三区视频| 欧美激情视频三区| 五月天激情开心网| 欧美视频精品一区| 国产传媒国产传媒| 精品一区二区三区在线观看 | 欧美午夜国产| 国产美女精品久久久| www.51av欧美视频| 亚洲欧美国产精品| 在线观看免费视频一区| 亚洲免费观看高清在线观看| www男人天堂| 国产精品外国| 午夜精品一区二区三区四区| 日韩免费电影| xxx一区二区| 超碰人人人人人人| 欧美日韩国产一区中文午夜| 最近中文字幕无免费| 日韩精品亚洲一区| 黄黄视频在线观看| 日韩极品少妇| 国产精品国内视频| 97caopor国产在线视频| 日韩av在线网站| 中文无码av一区二区三区| 亚洲女同女同女同女同女同69| 韩国三级hd两男一女| 视频一区二区中文字幕| 国产日产欧美一区二区| 欧美调教网站| 欧美理论片在线观看| 国产综合在线播放| 欧美在线色视频| 毛片aaaaa| 国产日韩欧美精品在线| 国产av天堂无码一区二区三区| 亚洲精品动态| 成人a免费视频| 欧亚在线中文字幕免费| 俺去啦;欧美日韩| 欧美捆绑视频| 欧美一级搡bbbb搡bbbb| 亚洲欧美日韩激情| 亚洲制服丝袜av| 国产视频123区| av成人老司机| 一区二区三区国产好的精华液| 国产精品免费看| 日本丰满大乳奶| 精品免费视频| 精品久久久久久综合日本 | 超碰97网站| 国精产品一区一区三区四川| 久久久久久高潮国产精品视| 最新国产在线观看| 精品无人区乱码1区2区3区在线| 97精品人妻一区二区三区香蕉| 欧美午夜精品久久久久久浪潮| 天堂网avav| 国产精品你懂的在线欣赏| 亚洲精品乱码久久| 日韩一级在线| 老司机午夜免费福利视频| 日韩欧美中字| 亚洲一区二区在线播放| 日本高清不卡一区二区三区视频| 欧美国产亚洲精品久久久8v| 色老头视频在线观看| 亚洲欧洲在线视频| 亚洲色图 校园春色| 精品国产精品网麻豆系列| 国产熟女一区二区丰满| 欧美日韩一级二级三级| 日韩欧美国产成人精品免费| 国产亚洲精品精华液| 呦呦视频在线观看| 成人午夜免费电影| 国产v亚洲v天堂无码久久久| 日韩午夜精品| 真人抽搐一进一出视频| 黄色工厂这里只有精品| 国产一区 在线播放| 卡通动漫国产精品| 99在线视频免费观看| 日韩高清二区| 99久久伊人精品影院| 国产色99精品9i| 亚洲已满18点击进入在线看片 | 欧美电影影音先锋| 91一区二区视频| 欧美人与性动xxxx| 91av久久久| 欧美一级片免费看| 国产黄色免费大片| 欧美成人精品高清在线播放| 国产1区在线观看| 亚洲黄色在线看| 青青草手机在线| 国产亚洲精品va在线观看| 国产区高清在线| 日韩视频在线免费观看| 黄色网址视频在线观看| 欧美伦理91i| 3344国产永久在线观看视频| 538国产精品一区二区免费视频| 欧美大片高清| 成人国产精品久久久| 欧美专区视频| 久久综合九色综合久99| 欧美日韩高清| 精品久久久无码人妻字幂| 日韩午夜激情| 另类小说第一页| 国产精品一品二品| 无需播放器的av| 激情成人综合网| 国产清纯白嫩初高中在线观看性色| 成人网页在线观看| 男人舔女人下部高潮全视频| 亚洲素人一区二区| 日韩av在线天堂| 欧美午夜在线观看| 亚洲av综合色区无码一二三区| 日韩福利在线播放| 日本在线免费| 97国产精品免费视频| av成人免费| 国产精品久久精品国产| 狠狠做六月爱婷婷综合aⅴ| 亚洲小说欧美另类激情| 国产欧美日韩一级| 亚洲黄色av片| 337p粉嫩大胆色噜噜噜噜亚洲| 国产又色又爽又高潮免费| 亚洲图片欧美综合| 国产乱码在线观看| 精品国产三级电影在线观看| 国产精品一二三区视频| 欧美精品亚州精品| 亚洲成人av观看| 岛国一区二区三区高清视频| 国产亚洲电影| 六月婷婷在线视频| 精品一区二区在线视频| 丰腴饱满的极品熟妇| 亚洲人吸女人奶水| 免费观看日批视频| 欧美成人欧美edvon| 欧美成人三区| 日韩av三级在线观看| 天堂久久av| 一区二区三区四区国产| 亚洲在线观看| 久草免费资源站| 亚洲欧美一区二区三区孕妇| 草莓视频18免费观看| 亚洲高清色综合| 免费av不卡在线观看| 国产精品一区二区三区在线播放 | 久久夜精品香蕉| 精品国产白色丝袜高跟鞋| 日本不卡免费高清视频| 成人爽a毛片免费啪啪红桃视频| 一区二区成人国产精品 | 不卡在线视频| 青青草一区二区| 福利片一区二区| av动漫在线播放| 国产麻豆欧美日韩一区| 最新黄色av网址| 欧美亚洲国产bt| 国产视频福利在线| 国产z一区二区三区| 日韩欧美美女在线观看| 欧美深夜福利视频| www.日韩av| 日本中文字幕免费| 亚洲大胆人体视频| sm在线观看| 国产精品二区在线观看| 欧美精品不卡| 风韵丰满熟妇啪啪区老熟熟女| 亚洲欧洲综合另类| 亚洲成人黄色片| 欧美激情精品久久久久久大尺度| 亚洲午夜精品| 水蜜桃色314在线观看| 成人美女视频在线观看18| 精品视频久久久久| 亚洲第一区在线观看| 精精国产xxxx视频在线野外| 精品国产一区二区三区日日嗨| 亚洲免费大片| 我和岳m愉情xxxⅹ视频| 色婷婷久久一区二区三区麻豆| 久久免费看视频| 国产免费一区视频观看免费| 99re6这里只有精品| 性一交一黄一片| 香蕉影视欧美成人| 蜜桃视频在线观看网站| 国产精品久久久久高潮| 久久婷婷蜜乳一本欲蜜臀| 亚洲色图欧美自拍| 亚洲午夜免费电影| 蜜桃成人在线视频| 国产一区二区在线免费视频| 中文在线日韩| 97精品人妻一区二区三区蜜桃| 欧美日韩综合视频网址| av福利在线播放| 亚洲最大的免费| 国产欧美日韩一区二区三区在线| 成年人网站免费看| 欧美日韩国产大片| 女人天堂av在线播放| 欧美裸体网站| 韩日欧美一区二区三区| 久久久精品国产sm调教| 亚洲人a成www在线影院| 不卡精品视频| 国产原创中文在线观看| 中文字幕不卡一区| 亚洲av无码专区在线| 日本一区二区不卡| 欧美一区精品| 久久久无码人妻精品一区| 欧美日韩久久一区二区| xxx性欧美| 午夜视频久久久| 成人美女视频在线观看18| 中文字幕在线一| 97免费中文视频在线观看| 97精品一区| 一起草在线视频| 91精品国产高清一区二区三区蜜臀| 9765激情中文在线| 免费看啪啪网站| 久久青草欧美一区二区三区| 国产乱人乱偷精品视频a人人澡| 欧美在线观看视频| 欧美成人一区二免费视频软件| 亚洲天堂岛国片| 亚洲精品国产精品乱码不99按摩 | а√天堂中文在线资源8|