日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

獲取雙異步返回值時,如何保證主線程不阻塞?

來源: 責編: 時間:2024-01-25 10:41:34 303觀看
導讀一、前情提要在上一篇文章中,使用雙異步后,如何保證數據一致性?,通過Future獲取異步返回值,輪詢判斷Future狀態,如果執行完畢或已取消,則通過get()獲取返回值,get()是阻塞的方法,因此會阻塞當前線程,如果通過new Runnable()執行

PXy28資訊網——每日最新資訊28at.com

一、前情提要

在上一篇文章中,使用雙異步后,如何保證數據一致性?,通過Future獲取異步返回值,輪詢判斷Future狀態,如果執行完畢或已取消,則通過get()獲取返回值,get()是阻塞的方法,因此會阻塞當前線程,如果通過new Runnable()執行get()方法,那么還是需要返回AsyncResult,然后再通過主線程去get()獲取異步線程返回結果。PXy28資訊網——每日最新資訊28at.com

寫法很繁瑣,還會阻塞主線程。PXy28資訊網——每日最新資訊28at.com

下面是FutureTask異步執行流程圖:PXy28資訊網——每日最新資訊28at.com

PXy28資訊網——每日最新資訊28at.com

二、JDK8的CompletableFuture

1、ForkJoinPool

Java8中引入了CompletableFuture,它實現了對Future的全面升級,可以通過回調的方式,獲取異步線程返回值。PXy28資訊網——每日最新資訊28at.com

CompletableFuture的異步執行通過ForkJoinPool實現, 它使用守護線程去執行任務。PXy28資訊網——每日最新資訊28at.com

ForkJoinPool在于可以充分利用多核CPU的優勢,把一個任務拆分成多個小任務,把多個小任務放到多個CPU上并行執行,當多個小任務執行完畢后,再將其執行結果合并起來。PXy28資訊網——每日最新資訊28at.com

Future的異步執行是通過ThreadPoolExecutor實現的。PXy28資訊網——每日最新資訊28at.com

PXy28資訊網——每日最新資訊28at.com

2、從ForkJoinPool和ThreadPoolExecutor探索CompletableFuture和Future的區別

  • ForkJoinPool中的每個線程都會有一個隊列,而ThreadPoolExecutor只有一個隊列,并根據queue類型不同,細分出各種線程池;
  • ForkJoinPool在使用過程中,會創建大量的子任務,會進行大量的gc,但是ThreadPoolExecutor不需要,因為ThreadPoolExecutor是任務分配平均的;
  • ThreadPoolExecutor中每個異步線程之間是相互獨立的,當執行速度快的線程執行完畢后,它就會一直處于空閑的狀態,等待其它線程執行完畢;
  • ForkJoinPool中每個異步線程之間并不是絕對獨立的,在ForkJoinPool線程池中會維護一個隊列來存放需要執行的任務,當線程自身任務執行完畢后,它會從其它線程中獲取未執行的任務并幫助它執行,直至所有線程執行完畢。

因此,在多線程任務分配不均時,ForkJoinPool的執行效率更高。但是,如果任務分配均勻,ThreadPoolExecutor的執行效率更高,因為ForkJoinPool會創建大量子任務,并對其進行大量的GC,比較耗時。PXy28資訊網——每日最新資訊28at.com

三、通過CompletableFuture優化 “通過Future獲取異步返回值”

1、通過Future獲取異步返回值關鍵代碼

(1)將異步方法的返回值改為Future<Integer>,將返回值放到new AsyncResult<>();中

@Async("async-executor")public void readXls(String filePath, String filename) {    try {     // 此代碼為簡化關鍵性代碼        List<Future<Integer>> futureList = new ArrayList<>();        for (int time = 0; time < times; time++) {            Future<Integer> sumFuture = readExcelDataAsyncFutureService.readXlsCacheAsync();            futureList.add(sumFuture);        }    }catch (Exception e){        logger.error("readXlsCacheAsync---插入數據異常:",e);    }}
@Async("async-executor")public Future<Integer> readXlsCacheAsync() {    try {        // 此代碼為簡化關鍵性代碼        return new AsyncResult<>(sum);    }catch (Exception e){        return new AsyncResult<>(0);    }}

(2)通過Future<Integer>.get()獲取返回值

public static boolean getFutureResult(List<Future<Integer>> futureList, int excelRow) {    int[] futureSumArr = new int[futureList.size()];    for (int i = 0;i<futureList.size();i++) {        try {            Future<Integer> future = futureList.get(i);            while (true) {                if (future.isDone() && !future.isCancelled()) {                    Integer futureSum = future.get();                    logger.info("獲取Future返回值成功"+"----Future:" + future                            + ",Result:" + futureSum);                    futureSumArr[i] += futureSum;                    break;                } else {                    logger.info("Future正在執行---獲取Future返回值中---等待3秒");                    Thread.sleep(3000);                }            }        } catch (Exception e) {            logger.error("獲取Future返回值異常: ", e);        }    }        boolean insertFlag = getInsertSum(futureSumArr, excelRow);    logger.info("獲取所有異步線程Future的返回值成功,Excel插入結果="+insertFlag);    return insertFlag;}

2、通過CompletableFuture獲取異步返回值關鍵代碼

(1)將異步方法的返回值改為 int

@Async("async-executor")public void readXls(String filePath, String filename) { List<CompletableFuture<Integer>> completableFutureList = new ArrayList<>();    for (int time = 0; time < times; time++) {     // 此代碼為簡化關鍵性代碼        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(new Supplier<Integer>() {         @Override         public Integer get() {             return readExcelDbJdk8Service.readXlsCacheAsyncMybatis();         }     }).thenApply((result) -> {// 回調方法         return thenApplyTest2(result);// supplyAsync返回值 * 1     }).thenApply((result) -> {         return thenApplyTest5(result);// thenApply返回值 * 1     }).exceptionally((e) -> { // 如果執行異常:         logger.error("CompletableFuture.supplyAsync----異常:", e);         return null;     });      completableFutureList.add(completableFuture);    }}
@Async("async-executor")public int readXlsCacheAsync() {    try {        // 此代碼為簡化關鍵性代碼        return sum;    }catch (Exception e){        return -1;    }}

(2)通過completableFuture.get()獲取返回值

public static boolean getCompletableFutureResult(List<CompletableFuture<Integer>> list, int excelRow){    logger.info("通過completableFuture.get()獲取每個異步線程的插入結果----開始");    int sum = 0;    for (int i = 0; i < list.size(); i++) {        Integer result = list.get(i).get();        sum += result;    }    boolean insertFlag = excelRow == sum;    logger.info("全部執行完畢,excelRow={},入庫={}, 數據是否一致={}",excelRow,sum,insertFlag);    return insertFlag;}

3、效率對比

(1)測試環境

  • 12個邏輯處理器的電腦;
  • Excel中包含10萬條數據;
  • Future的自定義線程池,核心線程數為24;
  • ForkJoinPool的核心線程數為24;

(2)統計四種情況下10萬數據入庫時間

  • 不獲取異步返回值
  • 通過Future獲取異步返回值
  • 通過CompletableFuture獲取異步返回值,默認ForkJoinPool線程池的核心線程數為本機邏輯處理器數量,測試電腦為12;
  • 通過CompletableFuture獲取異步返回值,修改ForkJoinPool線程池的核心線程數為24。

備注:因為CompletableFuture不阻塞主線程,主線程執行時間只有2秒,表格中統計的是異步線程全部執行完成的時間。PXy28資訊網——每日最新資訊28at.com

(3)設置核心線程數

將核心線程數CorePoolSize設置成CPU的處理器數量,是不是效率最高的?PXy28資訊網——每日最新資訊28at.com

// 獲取CPU的處理器數量int curSystemThreads = Runtime.getRuntime().availableProcessors() * 2;// 測試電腦是24

因為在接口被調用后,開啟異步線程,執行入庫任務,因為測試機最多同時開啟24線程處理任務,故將10萬條數據拆分成等量的24份,也就是10萬/24 = 4166,那么我設置成4200,是不是效率最佳呢?PXy28資訊網——每日最新資訊28at.com

測試的過程中發現,好像真的是這樣的。PXy28資訊網——每日最新資訊28at.com

自定義ForkJoinPool線程池
@Autowired@Qualifier("asyncTaskExecutor")private Executor asyncTaskExecutor;@Overridepublic void readXls(String filePath, String filename) {  List<CompletableFuture<Integer>> completableFutureList = new ArrayList<>();    for (int time = 0; time < times; time++) {  CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(new Supplier<Integer>() {         @Override         public Integer get() {             try {                 return readExcelDbJdk8Service.readXlsCacheAsync(sheet, row, start, finalEnd, insertBuilder);             } catch (Exception e) {                 logger.error("CompletableFuture----readXlsCacheAsync---異常:", e);                 return -1;             }         };     },asyncTaskExecutor);      completableFutureList.add(completableFuture); } // 不會阻塞主線程    CompletableFuture.allOf(completableFutureList.toArray(new CompletableFuture[completableFutureList.size()])).whenComplete((r,e) -> {        try {            int insertSum = getCompletableFutureResult(completableFutureList, excelRow);        } catch (Exception ex) {            return;        }    });}
自定義線程池
/** * 自定義異步線程池 */@Bean("asyncTaskExecutor")public AsyncTaskExecutor asyncTaskExecutor() {    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();    //設置線程名稱    executor.setThreadNamePrefix("asyncTask-Executor");    //設置最大線程數    executor.setMaxPoolSize(200);    //設置核心線程數    executor.setCorePoolSize(24);    //設置線程空閑時間,默認60    executor.setKeepAliveSeconds(200);    //設置隊列容量    executor.setQueueCapacity(50);    /**     * 當線程池的任務緩存隊列已滿并且線程池中的線程數目達到maximumPoolSize,如果還有任務到來就會采取任務拒絕策略     * 通常有以下四種策略:     * ThreadPoolExecutor.AbortPolicy:丟棄任務并拋出RejectedExecutionException異常。     * ThreadPoolExecutor.DiscardPolicy:也是丟棄任務,但是不拋出異常。     * ThreadPoolExecutor.DiscardOldestPolicy:丟棄隊列最前面的任務,然后重新嘗試執行任務(重復此過程)     * ThreadPoolExecutor.CallerRunsPolicy:重試添加當前的任務,自動重復調用 execute() 方法,直到成功     */    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());    executor.initialize();    return executor;}

PXy28資訊網——每日最新資訊28at.com

(4)統計分析

效率對比:PXy28資訊網——每日最新資訊28at.com

③通過CompletableFuture獲取異步返回值(12線程) <  ②通過Future獲取異步返回值 <  ④通過CompletableFuture獲取異步返回值(24線程) <  ①不獲取異步返回值PXy28資訊網——每日最新資訊28at.com

不獲取異步返回值時性能最優,這不廢話嘛~PXy28資訊網——每日最新資訊28at.com

核心線程數相同的情況下,CompletableFuture的入庫效率要優于Future的入庫效率,10萬條數據大概要快4秒鐘,這還是相當驚人的,優化的價值就在于此。PXy28資訊網——每日最新資訊28at.com

PXy28資訊網——每日最新資訊28at.com

四、通過CompletableFuture.allOf解決阻塞主線程問題

1、語法

CompletableFuture.allOf(CompletableFuture的可變數組).whenComplete((r,e) -> {})。PXy28資訊網——每日最新資訊28at.com

2、代碼實例

getCompletableFutureResult方法在 “3.2.2 通過completableFuture.get()獲取返回值”。PXy28資訊網——每日最新資訊28at.com

// 不會阻塞主線程CompletableFuture.allOf(completableFutureList.toArray(new   CompletableFuture[completableFutureList.size()])).whenComplete((r,e) -> {    logger.info("全部執行完畢,解決主線程阻塞問題~");    try {        int insertSum = getCompletableFutureResult(completableFutureList, excelRow);    } catch (Exception ex) {        logger.error("全部執行完畢,解決主線程阻塞問題,異常:", ex);        return;    }});// 會阻塞主線程//getCompletableFutureResult(completableFutureList, excelRow);logger.info("CompletableFuture----會阻塞主線程嗎?");

PXy28資訊網——每日最新資訊28at.com

五、CompletableFuture中花俏的語法糖

1、runAsync

runAsync 方法不支持返回值。PXy28資訊網——每日最新資訊28at.com

可以通過runAsync執行沒有返回值的異步方法。PXy28資訊網——每日最新資訊28at.com

不會阻塞主線程。PXy28資訊網——每日最新資訊28at.com

// 分批異步讀取Excel內容并入庫int finalEnd = end;CompletableFuture.runAsync(() -> readExcelDbJdk8Service.readXlsCacheAsyncMybatis();

2、supplyAsync

supplyAsync也可以異步處理任務,傳入的對象實現了Supplier接口。將Supplier作為參數并返回CompletableFuture結果值,這意味著它不接受任何輸入參數,而是將result作為輸出返回。PXy28資訊網——每日最新資訊28at.com

會阻塞主線程。PXy28資訊網——每日最新資訊28at.com

supplyAsync()方法關鍵代碼:PXy28資訊網——每日最新資訊28at.com

int finalEnd = end;CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(new Supplier<Integer>() {    @Override    public Integer get() {        return readExcelDbJdk8Service.readXlsCacheAsyncMybatis();    }});
@Overridepublic int readXlsCacheAsyncMybatis() {    // 不為人知的操作    // 返回異步方法執行結果即可 return 100;}

六、順序執行異步任務

1、thenRun

thenRun()不接受參數,也沒有返回值,與runAsync()配套使用,恰到好處。PXy28資訊網——每日最新資訊28at.com

// JDK8的CompletableFutureCompletableFuture.runAsync(() -> readExcelDbJdk8Service.readXlsCacheAsyncMybatis()).thenRun(() -> logger.info("CompletableFuture----.thenRun()方法測試"));

PXy28資訊網——每日最新資訊28at.com

2、thenAccept

thenAccept()接受參數,沒有返回值。PXy28資訊網——每日最新資訊28at.com

supplyAsync + thenAcceptPXy28資訊網——每日最新資訊28at.com

  • 異步線程順序執行
  • supplyAsync的異步返回值,可以作為thenAccept的參數使用
  • 不會阻塞主線程
CompletableFuture.supplyAsync(new Supplier<Integer>() {    @Override    public Integer get() {        return readExcelDbJdk8Service.readXlsCacheAsyncMybatis();    }}).thenAccept(x -> logger.info(".thenAccept()方法測試:" + x));

PXy28資訊網——每日最新資訊28at.com

但是,此時無法通過completableFuture.get()獲取supplyAsync的返回值了。PXy28資訊網——每日最新資訊28at.com

3、thenApply

thenApply在thenAccept的基礎上,可以再次通過completableFuture.get()獲取返回值。PXy28資訊網——每日最新資訊28at.com

supplyAsync + thenApply,典型的鏈式編程。PXy28資訊網——每日最新資訊28at.com

  • 異步線程內方法順序執行。
  • supplyAsync 的返回值,作為第 1 個thenApply的參數,進行業務處理。
  • 第 1 個thenApply的返回值,作為第 2 個thenApply的參數,進行業務處理。
  • 最后,通過future.get()方法獲取最終的返回值。
CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(new Supplier<Integer>() { @Override    public Integer get() {        return readExcelDbJdk8Service.readXlsCacheAsyncMybatis();    }}).thenApply((result) -> {    return thenApplyTest2(result);// supplyAsync返回值 * 2}).thenApply((result) -> {    return thenApplyTest5(result);// thenApply返回值 * 5});logger.info("readXlsCacheAsyncMybatis插入數據 * 2 * 5 = " + completableFuture.get());

PXy28資訊網——每日最新資訊28at.com

七、CompletableFuture合并任務

  • thenCombine,多個異步任務并行處理,有返回值,最后合并結果返回新的CompletableFuture對象。
  • thenAcceptBoth,多個異步任務并行處理,無返回值。
  • acceptEither,多個異步任務并行處理,無返回值。
  • applyToEither,,多個異步任務并行處理,有返回值。

CompletableFuture合并任務的代碼實例,這里就不多贅述了,一些語法糖而已,大家切記陷入低水平勤奮的怪圈。PXy28資訊網——每日最新資訊28at.com

八、CompletableFuture VS Future總結

本文中以下幾個方面對比了CompletableFuture和Future的差異:PXy28資訊網——每日最新資訊28at.com

  • ForkJoinPool和ThreadPoolExecutor的實現原理,探索了CompletableFuture和Future的差異。
  • 通過代碼實例的形式簡單介紹了CompletableFuture中花俏的語法糖。
  • 通過CompletableFuture優化了 “通過Future獲取異步返回值”。
  • 通過CompletableFuture.allOf解決阻塞主線程問題。

Future提供了異步執行的能力,但Future.get()會通過輪詢的方式獲取異步返回值,get()方法還會阻塞主線程。PXy28資訊網——每日最新資訊28at.com

輪詢的方式非常消耗CPU資源,阻塞的方式顯然與我們的異步初衷背道而馳。PXy28資訊網——每日最新資訊28at.com

JDK8提供的CompletableFuture實現了Future接口,添加了很多Future不具備的功能,比如鏈式編程、異常處理回調函數、獲取異步結果不阻塞不輪詢、合并異步任務等。PXy28資訊網——每日最新資訊28at.com

獲取異步線程結果后,我們可以通過添加事務的方式,實現Excel入庫操作的數據一致性。PXy28資訊網——每日最新資訊28at.com

異步多線程情況下如何實現事務?PXy28資訊網——每日最新資訊28at.com

有的小伙伴可能會說:PXy28資訊網——每日最新資訊28at.com

這還不簡單?添加@Transactional注解,如果發生異?;蛉霂鞌祿坎环?,直接回滾就可以了~PXy28資訊網——每日最新資訊28at.com

那么,真的是這樣嗎?我們下期見~PXy28資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-67849-0.html獲取雙異步返回值時,如何保證主線程不阻塞?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Node問題:如何正確安裝nvm?Mac和Win雙教程!

下一篇: lowcode-cms開源社區源碼設計分享

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
亚洲精品一级| 国产精品高潮呻吟久久| 欧美一级大片在线观看| 亚洲一区二区三区精品动漫| aaa亚洲精品一二三区| 99精品欧美一区二区蜜桃免费| 日韩一区二区免费高清| 中文一区在线| 中日韩美女免费视频网站在线观看| 尤妮丝一区二区裸体视频| 激情视频一区二区| 亚洲激情网站| 一区二区三区色| 欧美一区二区三区免费大片| 久久精品导航| 欧美a级片网站| 欧美高清视频一区二区三区在线观看| 牛夜精品久久久久久久99黑人| 欧美激情一区二区三区| 国产精品成人免费| 国内精品视频在线播放| 狠狠色丁香久久婷婷综合丁香 | 亚洲动漫精品| 99re66热这里只有精品3直播| 一本一本大道香蕉久在线精品| 亚洲主播在线| 久久久免费精品| 欧美日韩免费观看一区| 国产精品综合不卡av| 欲色影视综合吧| 一区二区三区四区精品| 校园激情久久| 欧美电影打屁股sp| 国产精品私拍pans大尺度在线| 国产一区二区三区在线免费观看| 亚洲国产精品va在线看黑人动漫| 一区二区欧美激情| 久久久国产精品一区二区中文| 欧美理论电影在线观看| 国产色产综合色产在线视频| 亚洲精品乱码| 欧美一区二区在线观看| 欧美成人一品| 国产欧美一区二区三区视频| 最新日韩在线视频| 欧美一区二区三区久久精品茉莉花 | 国内在线观看一区二区三区 | 亚洲第一天堂av| 亚洲国产高清在线观看视频| 亚洲自拍另类| 欧美黄色大片网站| 国内精品视频在线播放| 亚洲婷婷综合久久一本伊一区| 久久久久免费观看| 欧美午夜精品久久久久久久| 怡红院精品视频| 亚洲欧美综合v| 欧美福利一区| 国产视频亚洲精品| 亚洲精品社区| 久久亚洲国产精品一区二区| 国产精品久久久久av免费| 亚洲国产精品一区在线观看不卡| 午夜精品在线看| 欧美日韩午夜在线视频| 国产在线高清精品| 日韩一级网站| 中日韩视频在线观看| 裸体丰满少妇做受久久99精品 | 欧美激情成人在线| 国内精品视频一区| 午夜精品福利在线| 欧美久久成人| 亚洲黄网站黄| 久久裸体视频| 国产一区二区三区奇米久涩| 国内精品久久久久影院薰衣草| 亚洲视频免费| 欧美日本一道本| 亚洲国产精品999| 久久免费精品视频| 国产色产综合色产在线视频| 一区二区三区免费看| 女仆av观看一区| 亚洲国产高清在线观看视频| 久久久中精品2020中文| 国产欧美日本一区视频| 亚洲一区二区三区影院| 欧美精品在线免费| 伊人狠狠色j香婷婷综合| 久久av一区二区| 欧美性视频网站| 欧美伦理影院| 影音先锋久久| 欧美激情中文字幕一区二区| 狠狠色伊人亚洲综合成人| 欧美一区二区三区播放老司机| 国产精品久久久久久久7电影| 99精品欧美一区二区三区| 久久久久久亚洲精品中文字幕| 国产欧美一二三区| 欧美一区国产在线| 国产日韩欧美日韩| 一区二区欧美国产| 欧美视频一区在线观看| 亚洲国产精选| 亚洲欧美国产va在线影院| 欧美日韩在线第一页| 韩国福利一区| 久久久国产精彩视频美女艺术照福利 | 亚洲香蕉网站| 国产精品日韩在线一区| 亚洲欧美日韩精品久久久久| 国产精品久久久久久久久婷婷| 亚洲一区二区动漫| 国产欧美一区二区白浆黑人| 欧美在线视频二区| 黄色在线成人| 老色鬼久久亚洲一区二区| 亚洲激情在线| 欧美视频在线看| 国产模特精品视频久久久久| 欧美一区观看| 伊人一区二区三区久久精品| 欧美日韩精品欧美日韩精品 | 亚洲欧美中文在线视频| 国产欧美精品日韩| 久久国产精品网站| 欧美区二区三区| 亚洲区在线播放| 欧美日韩国产成人在线91| 亚洲美女视频在线观看| 久久免费观看视频| 亚洲国产精品va在线看黑人动漫| 欧美高清一区二区| 妖精视频成人观看www| 国产精品卡一卡二| 久久精品导航| 亚洲精品乱码久久久久久久久 | 欧美日韩一区二区三区免费| 亚洲午夜一区二区| 国产在线日韩| 麻豆久久婷婷| 国产精品99久久久久久宅男 | 亚洲手机视频| 国内精品免费在线观看| 欧美激情一区二区三区在线| 亚洲一区精彩视频| 黄网动漫久久久| 乱人伦精品视频在线观看| 国产一区二区三区直播精品电影| 狠狠色综合色综合网络| 久久免费高清| 午夜精品亚洲| 欧美国产日韩精品免费观看| 亚洲日韩成人| 欧美日本不卡| 亚洲影院免费观看| 在线成人中文字幕| 欧美午夜精彩| 久久精品一区二区三区四区| 亚洲精品久久久久久久久久久久| 国产精品九九久久久久久久| 久久伊人一区二区| 亚洲在线网站| 亚洲国内高清视频| 国产欧美在线看| 欧美日韩欧美一区二区| 久久国产精品一区二区三区四区| 亚洲精品在线观看免费| 国产一区二区中文字幕免费看| 欧美三级在线| 欧美激情一区在线观看| 久久综合九九| 久久久噜噜噜久噜久久| 小黄鸭精品aⅴ导航网站入口| 中日韩男男gay无套| 日韩视频精品在线| 亚洲国产精品一区制服丝袜| 红桃av永久久久| 国产一级久久| 国产无一区二区| 国产女精品视频网站免费| 国产精品久久激情| 欧美性猛交99久久久久99按摩| 欧美日韩精品综合| 欧美精品一线| 欧美美女福利视频| 欧美精品精品一区| 欧美激情视频在线免费观看 欧美视频免费一 | 久久国产加勒比精品无码| 亚洲一区二区三区精品视频| 一区二区三区|亚洲午夜| 亚洲精品中文字幕在线观看| 亚洲国产精品久久| 亚洲大片一区二区三区| 怡红院精品视频| 在线成人激情视频| 1024国产精品| 亚洲第一中文字幕在线观看| 在线欧美影院| 亚洲国产日韩欧美| 亚洲片在线观看| 亚洲毛片播放|