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

多線程引發的慘案直接把年終給干沒了

開發 前端
看完本文,相信大家對 Threadlocal 與 InheritableThreadLocal 的使用及其底層原理的掌握已不存在疑問,這也提醒我們熟練地掌握一個組件或一項技術最好的方式還是熟讀它的源碼,畢竟源碼之下無秘密,當我們使用到別人封裝好的組件或類時,如果有興趣也可以也看一下它的源碼,以本文為例,其實我們工程中多處地方都使用了 Context.getContext().getClientIn

你好,我是坤哥

前些日子我們線上出現了一個比較嚴重的故障,這個故障是多線程使用不當引起的,挺有代表性的,所以分享給大家,希望能幫大家避坑。

問題簡述

先簡單介紹一下問題產生的背景,我們有個返利業務,其中有個搜索場景,這個場景是用戶在 app 輸入搜索關鍵詞,然后 server 會根據這個關鍵詞到各個平臺(如淘寶,京東,拼多多等)調一下搜索接口,聚合這些搜索結果后再返回給用戶,最開始這個搜索場景處理是單線程的,但隨著接入的平臺越來越多,搜索請求耗時也越來越長,由于每個平臺的搜索請求都是獨立的,很顯然,單線程是可以優化為多線程的,如下:

圖片

這樣的話,搜索請求的耗時就只取決于搜索接口耗時最長的那個平臺,所以使用多線程顯然對接口性能是一個極大的優化,但使用多線程改造上線后,短時間內社群中有多名用戶反饋前臺展示「APP 需要升級的提示」,經定位后發現是因為在多線程中無法獲取客戶端信息,由于客戶端信息缺失,導致返回給用戶需要升級的提示,偽代碼如下:

// 開啟多線程處理
new Thread(new Runnable() {
@Override
public void run() {
Map clientInfoMap = Context.getContext().getClientInfo();
// 無法獲取客戶端信息,返回需要升級的信息
if (clientInfoMap == null) {
throw new Exception("版本號過低,請升級版本");
}
String version = clientInfoMap.get("version");


// 以下正常邏輯
....
}
}).start();

畫外音:在生產中多線程使用的是線程池來實現,這里為了方便演示,直接 new Thread,效果都一樣,大家知道即可。

那么問題來了,改成多線程后客戶端信息怎么就取不到了呢?要搞清楚這個問題,就得先了解客戶端信息是如何存儲的了。

Threadlocal 簡介

不同客戶端請求的客戶端信息(wifi 還是 4G,機型,app名稱,電量等)顯然不一樣,dubbo 業務線程拿到客戶端請求后首先會將有用的請求信息提取出來(如本文中的 Map clientInfo),但這個 clientInfo 可能會在線程調用的各個方法中用到,于是如何存儲就成為了一個現實的問題,相信有經驗的朋友一下就想到了,沒錯,用 Threadlocal !為什么用它,它有什么優勢,簡單來說有兩點:

  1. 無鎖化提升并發性能
  2. 簡化變量的傳遞邏輯

1.無鎖化提升并發性能

先說第一個,無鎖化提升并發性能,影響并發的原因有很多,其中一個很重要的原因就是鎖,為了防止對共享變量的競用,不得不對共享變量加鎖。

圖片

如果對共享變量爭用的線程數增多,顯然會嚴重影響系統的并發度,最好的辦法就是使用“影分身術”為每個線程都創建一個線程本地變量,這樣就避免了對共享變量的競用,也就實現了無鎖化。

圖片

無鎖化

ThreadLocal 即線程本地變量,它可以為每個線程創建一份線程本地變量,使用方法如下:

static ThreadLocal<SimpleDateFormat> threadLocal1 = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};

public String formatDate(Date date) {
return threadLocal1.get().format(date);
}

這樣的話每個線程就獨享一份與其他線程無關的 SimpleDateFormat 實例副本,它們調用 formatDate 時使用的 SimpleDateFormat 實例也是自己獨有的副本,無論對副本怎么操作對其他線程都互不影響。

通過以上例子我們可以看出,可以通過 new ThreadLocal+ initialValue 來為創建的 ThreadLocal 實例初始化本地變量(initialValue 方法會在首次調用 get 時被調用以初始化本地變量)。當然,如果之后需要修改本地變量的話,也可以用以下方式來修改。

threadLocal1.set(new SimpleDateFormat("yyyy-MM-dd"))

而使用 threadLocal1.get()這樣的方法即可獲得線程本地變量。

可能一些朋友會好奇線程本地變量是如何存儲的,一圖勝千言。

圖片

每一個線程(Thread)內部都有一個 ThreadLocalMap, ThreadLocal 的 get 和 set 操作其實在底層都是針對 ThreadLocalMap 進行操作的。

public class Thread implements Runnable {
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
}

它與 HashMap 類似,存儲的都是鍵值對,只不過每一項(Entry)中的 key 為 threadlocal 變量(如上文案例中的 threadLocal1),value 才為我們要存儲的值(如上文中的 SimpleDateFormat 實例),此外它們在碰到 hash 沖突時的處理策略也不同,HashMap 在碰到 hash 沖突時采用的是鏈表法,而 ThreadLocalMap 采用的是線性探測法。

2.簡化變量的傳遞邏輯

接下來我們來看使用 ThreadLocal 的等二個好處,簡化變量的傳遞邏輯,線程在處理業務邏輯時可能會調用幾十個方法,如果這些方法中只有幾個需要用到 clientInfo,難道要在這幾十個方法中定義一個 clientInfo 參數來層層傳遞嗎,顯然不現實。那該怎么辦呢,使用 ThreadLocal 即可解決此問題。由上文可知通過 ThreadLocal 設置的本地變量是同 threadlocal 一起保存在 Thread 的 ThreadLocalMap 這個內部類中的,所以可在線程調用的任意方法中取出,偽代碼如下:

public class ThreadLocalWithUserContext implements Runnable {

private static ThreadLocal<Map<String,String>> threadLocal
= new ThreadLocal<>();

@Override
public void run() {
// clientInfo 初始化
Map<String, String> clientInfo = xxx;
threadLocal.set(clientInfo);
test1();
}

public void test1() {
test2();
}

public void test2() {
testX();
}
...

public void testX() {
Map clientInfo = threadLocal.get();
}
}

中間定義的任何方法都無需為了傳遞 clientInfo 而定義一個額外的變量,代碼優雅了不少。

由以上分析可知,使用 ThreadLocal 確實比較方便,在此我們先停下來思考一個問題:如果線程在調用過程中只用到一個 clientInfo 這樣的信息,只定義一個 ThreadLocal 變量當然就夠了,但實際上在使用過程中我們可能要傳遞多個類似 clientInfo 這樣的信息(如 userId,cookie,header),難道因此要定義多個 ThreadLocal 變量嗎,這么做不是不可以,但不夠優雅,更合適的做法是我們只定義一個 ThreadLocal 變量,變量存的是一個上下文對象,其他像 clientInfo,userId,header 等信息就作為此上下文對象的屬性即可,代碼如下:

public final class Context {

private static final ThreadLocal<Context> LOCAL = new ThreadLocal<Context>() {
protected Context initialValue() {
return new Context();
}
};


private Long uid; // 用戶uid
private Map<String, String> clientInfo; // 客戶端信息
private Map<String, String> headers = null; // 請求頭信息
private Map<String, Map<String, String>> cookies = null; // 請求 cookie

public static Context getContext() {
return (Context) LOCAL.get();
}

}

這樣的話我們可通過 Context.getContext().getXXX() 的形式來獲取線程所需的信息,通過這樣的方式我們不僅避免了定義無數 ThreadLocal 變量的煩惱,而且還收攏了上下文信息的管理。

通過以上介紹相信大家也都知道了 clientInfo 其實是借由 ThreadLocal 存儲的,認清了這個事實后那我們現在再回頭看開頭的生產問題:將單線程改成多線程后,為什么在新線程中就拿不到 clientInfo 了?

問題剖析

源碼之下無秘密,我們查看一下源碼來一探究竟,獲取本地變量的值使用的是 ThreadLocal.get 方法,那就來看下這個方法。

public class ThreadLocal<T> {
public T get() {
// 1.先獲取當前線程
Thread t = Thread.currentThread();
// 2.再獲取當前線程的 ThreadLocalMap
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
}

可以看到 get 方法主要步驟如下:

  1. 首先需要獲取當前線程
  2. 其次獲取當前線程的 ThreadLocalMap
  3. 進而再去獲取相應的本地變量值
  4. 如果沒有的話則調用 initiaValue 方法來初始化本地變量

由此可知當我們調用 threadlocal.get  時,會拿到當前線程的 ThreadLocalMap,然后再去拿 entry 中的本地變量,而對多線程來說,新線程的 ThreadLocalMap 里面的東西本來就未做任何設置,是空的,拿不到線程本地變量也就合情合理了。

解決方案

問題清楚了,那怎么解決呢,不難得知主要有兩種方案:

1.我們之前是在新線程的執行方法中調用 threadlocal.get 方法,可以改成先從當前執行線程中調用 threadlocal.get 獲得 clientInfo,然后再把 clientInfo 傳入新線程,偽代碼如下:

// 先從當前線程的 Context 中獲取 clientInfo
Map clientInfoMap = Context.getContext().getClientInfo();
new Thread(new Runnable() {
@Override
public void run() {
// 此時的 clientInfoMap 由于是在新線程創建前獲取的,肯定是有值的
String version = clientInfoMap.get("version");


// 以下正常邏輯
....
}
}).start();

2.只需把 ThreadLocal 換成 InheritableThreadLocal,如下:

public final class Context {
private static final InheritableThreadLocal<Context> LOCAL = new InheritableThreadLocal<Context>() {
protected Context initialValue() {
return new Context();
}
};

public static Context getContext() {
return (Context) LOCAL.get();
}
}

new Thread(new Runnable() {
@Override
public void run() {
// 此時的 clientInfo 能正常獲取到
Map clientInfo = Context.getContext().getClientInfo();
String version = clientInfo.get("version");
// 以下正常邏輯
....
}
}).start();

為什么 InheritableThreadLocal 能有這么神奇,背后的原理是什么?

由前文介紹我們得知,ThreadLocal 變量最終是存在 ThreadLocalMap 中的,那么能否在創建新線程的時候,把當前線程的 ThreadLocalMap 復制給新線程的 ThreadLocalMap 呢,這樣的話即便你從新線程中調用 threadlocal.get 也照樣能獲得對應的本地變量,和 InheritableThreadLocal 相關的底層干的就是這個事,我們先來瞧一瞧 InheritableThreadLocal 長啥樣。

public class InheritableThreadLocal<T> extends ThreadLocal<T> {

ThreadLocalMap getMap(Thread t) {
return t.inheritableThreadLocals;
}

void createMap(Thread t, T firstValue) {
t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
}
}

由此可知 InheritableThreadLocal 其實是繼承自 ThreadLocal 類的,此外我們在 getMap 和 createMap 這兩個方法中也發現它的底層其實是用 inheritableThreadLocals 來存儲的,而 ThreadLocal 用的是 threadLocals 變量存儲的。

public class Thread implements Runnable {
// ThreadLocal 實例的底層存儲
ThreadLocal.ThreadLocalMap threadLocals = null;

// inheritableThreadLocals 實例的底層存儲
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
}

知道了這些,我們再來看下創建線程時涉及到的 inheritableThreadLocals 復制相關的關鍵代碼如下:

public
class Thread implements Runnable {
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}

private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null, true);
}

private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
...
Thread parent = currentThread();
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
// 將當前線程的 inheritableThreadLocals 復制給新創建線程的 inheritableThreadLocals
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
}
}

由此可知,在創建新線程時,在初始化時其實相關邏輯是幫我們干了復制 inheritableThreadLocals 的操作,至此真相大白。

總結

看完本文,相信大家對 Threadlocal 與 InheritableThreadLocal 的使用及其底層原理的掌握已不存在疑問,這也提醒我們熟練地掌握一個組件或一項技術最好的方式還是熟讀它的源碼,畢竟源碼之下無秘密,當我們使用到別人封裝好的組件或類時,如果有興趣也可以也看一下它的源碼,以本文為例,其實我們工程中多處地方都使用了 Context.getContext().getClientInfo();這樣的獲取客戶端信息的形式,用慣了導致在多線程環境下沒有引起警惕,以致踩了坑。

另外需要注意的是 ThreadLocal 使用不當可能導致內存泄漏,需要在線程結束后及時 remove 掉,這些技術細節不是本文重點,故而沒有深入詳解,有興趣的大家可以去查閱相關資料。

責任編輯:武曉燕 來源: 碼海
相關推薦

2017-08-22 15:58:56

2021-11-01 17:29:02

Windows系統Fork

2017-08-24 17:37:18

DNS緩存分析

2023-01-26 11:43:03

線程池CPUJava

2019-08-14 10:49:20

Python編程語言代碼

2024-05-13 08:37:17

炫技H5UI

2024-07-12 08:52:50

2025-10-10 08:23:56

2011-04-27 10:02:54

兼容墨盒用戶體驗

2013-03-22 10:53:42

PyConPython

2021-07-24 13:11:19

Redis數據技術

2010-02-25 15:22:02

2018-04-07 17:13:12

密碼慘案服務器

2017-09-01 09:17:51

DNS緩存慘案

2022-06-08 10:01:23

性能優化慢查詢

2025-07-21 06:30:00

2025-03-31 08:30:00

2019-10-30 21:27:51

Java中央處理器電腦

2017-12-08 19:55:43

程序員美團年終獎金

2009-03-12 10:52:43

Java線程多線程
點贊
收藏

51CTO技術棧公眾號

狠狠狠色丁香婷婷综合激情| 日本一区二区免费高清| 亚洲高清在线精品| 欧美性色黄大片人与善| 在线观看视频二区| 激情丁香综合| 中文字幕在线国产精品| 色哟哟网站在线观看| 亚洲天堂av影院| 中文字幕亚洲一区二区av在线| 97se视频在线观看| 免费观看日批视频| 黄色精品免费| 在线国产精品播放| 亚洲一区和二区| 九九热这里有精品| 亚洲国产精品欧美一二99| 日本一区二区三区视频在线观看 | 亚洲黄色免费视频| 日韩第一区第二区| 欧美网站大全在线观看| 日韩国产一级片| 欧美18hd| 国产日韩欧美一区二区三区乱码| 亚洲自拍偷拍区| 国产精品无码粉嫩小泬| 亚洲乱亚洲高清| 久久这里只有精品99| 偷拍夫妻性生活| 东京久久高清| 欧美一区二区三区在线观看| 国产精品亚洲a| 国产嫩草在线视频| 亚洲男人天堂av网| 日韩欧美精品在线不卡 | 色99之美女主播在线视频| 日本一区二区在线免费观看| 成人激情久久| 欧美日韩亚洲丝袜制服| 无码精品国产一区二区三区免费| av有码在线观看| 一区二区三区日韩精品视频| 亚洲精品一区二区三区四区五区| 性猛交xxxx| 成人午夜电影网站| 97中文在线| 99热这里只有精品9| 久久99久久久欧美国产| 国产精品美乳在线观看| 亚洲成熟少妇视频在线观看| 午夜在线视频一区二区区别 | 国产精品久久亚洲不卡| 欧美日韩免费观看中文| 男女视频网站在线观看| heyzo中文字幕在线| 一区二区日韩av| 尤物国产精品| 欧美jizzhd69巨大| 中文字幕制服丝袜成人av| 亚洲国内在线| 黄色片网站在线| 亚洲欧美日韩系列| 久久视频免费在线| 91中文在线| 一区二区日韩av| 三上悠亚久久精品| 欧美男人天堂| 色婷婷精品久久二区二区蜜臂av| 黄色片久久久久| 97成人超碰| 91精品国产综合久久香蕉的特点| 天天色天天干天天色| 视频在线亚洲| 日韩精品在线免费观看| 一级黄色性视频| 色婷婷热久久| 欧美成人免费视频| 国产一级特黄aaa大片| 最新国产拍偷乱拍精品| 日本视频久久久| 91免费视频播放| 国产乱码精品一区二区三区五月婷| 999国产在线| 五月激情丁香婷婷| 国产精品美女久久久久久| www.黄色网址.com| 欧美极品videos大乳护士| 欧美三级在线播放| 性活交片大全免费看| 最新亚洲精品| 蜜月aⅴ免费一区二区三区 | 在线播放国产精品二区一二区四区 | 最新黄色av网址| 欧美.日韩.国产.一区.二区| 69视频在线免费观看| 在线免费观看日韩视频| 成人精品小蝌蚪| 亚洲bbw性色大片| 超碰97国产精品人人cao| 日韩欧美综合在线视频| 黄色三级视频在线播放| 天天躁日日躁狠狠躁欧美巨大小说| 国产一区二区三区久久精品| 欧美又粗又大又长| 日韩成人一区二区| 大波视频国产精品久久| av福利在线播放| 五月婷婷激情综合| 天堂在线中文在线| 狼人精品一区二区三区在线 | 欧美日韩在线一区二区三区| 国产素人视频在线观看| 色欧美片视频在线观看| 亚洲图片欧美另类| 99免费精品| 国产91在线视频| 少妇人妻精品一区二区三区| 中文字幕在线一区免费| 九九视频精品在线观看| 老司机精品在线| 欧美成人亚洲成人日韩成人| 性色av一区二区三区四区| 91蝌蚪国产九色| 国产手机免费视频| 日韩高清一区| 精品国产一区二区三区久久| 波多野结衣高清在线| 97精品国产97久久久久久久久久久久 | 无人码人妻一区二区三区免费| 九九久久成人| 欧美中文字幕视频| 视频一区二区免费| 亚洲一区二区三区国产| 超碰在线超碰在线| 国产精品久久久久久久免费观看 | 91精品国产91久久久久久最新 | 中文字幕日韩欧美在线| 无码人妻丰满熟妇奶水区码| 91在线精品秘密一区二区| 成年人看的毛片| 福利在线一区| 久久久久久亚洲精品中文字幕| 不卡的日韩av| 亚洲精品日产精品乱码不卡| 搡的我好爽在线观看免费视频| 99re6这里只有精品| 国产精品美女久久久久久免费 | 欧美国产乱子伦| 人妻无码视频一区二区三区| 久久综合亚洲| 国产精品第2页| 成人亚洲性情网站www在线观看| 一本色道久久综合狠狠躁的推荐| 国产又爽又黄无码无遮挡在线观看| 亚洲毛片视频| 精品日本一区二区三区在线观看| 第一福利在线视频| 亚洲精品有码在线| 国产主播第一页| 国产精品丝袜在线| 黄色aaaaaa| 欧美日韩在线大尺度| 国产精品日韩二区| 国产精品一区二区av影院萌芽| 亚洲欧美在线一区二区| 午夜精品免费观看| 中文字幕色av一区二区三区| 视频免费1区二区三区| 欧美va天堂| 精品国产福利| 日本成人福利| 久久精品福利视频| 成人毛片在线精品国产| 精品久久久精品| 亚洲一二三精品| 国产一区不卡视频| 免费国产a级片| 成人aaaa| 7777奇米亚洲综合久久| av中文在线资源库| 中文字幕在线日韩| 国产 日韩 欧美 精品| 色综合一个色综合| 超碰手机在线观看| 2019国产精品| 国产精品igao网网址不卡| 亚洲一区二区免费看| 一区二区三区不卡在线| 天堂精品久久久久| 国产精欧美一区二区三区| 免费黄网站在线| 日韩精品一二三四区| 97人妻人人澡人人爽人人精品| 午夜欧美在线一二页| 91动漫免费网站| av影院午夜一区| 成人av毛片在线观看| 国产午夜精品一区二区三区欧美 | 亚洲欧美日韩精品一区二区| 精品久久免费观看| 在线日韩一区| 国产厕所精品在线观看| 国产亚洲人成a在线v网站| 久久久久久久999精品视频| 3p在线观看| 亚洲免费一在线| 丰满熟妇乱又伦| 3751色影院一区二区三区| 中文字幕av影院| 亚洲一区在线播放| a一级免费视频| 94色蜜桃网一区二区三区| 爽爽爽在线观看| 天堂午夜影视日韩欧美一区二区| 国产乱子伦精品视频| 日韩中文在线电影| 欧洲国产精品| 欧美日韩精品一区二区三区在线观看| 91精品视频在线看| 91国内外精品自在线播放| 2018日韩中文字幕| 男插女视频久久久| 久久亚洲精品视频| 日本www在线观看视频| 日韩精品亚洲视频| 网站黄在线观看| 精品国产人成亚洲区| 国产理论片在线观看| 欧美日韩国产一级二级| 欧美性猛交xxxx乱大交hd | 国产精品国产一区二区三区四区| 日韩欧美一区二区三区| 欧美一二三区视频| 亚洲成人av一区二区| 久久在线视频精品| 亚洲国产wwwccc36天堂| 久草中文在线视频| 亚洲午夜三级在线| 久久久久亚洲av成人片| 亚洲靠逼com| 全程偷拍露脸中年夫妇| 亚洲免费观看高清| 国产极品国产极品| 一区二区三区影院| 国产亚洲第一页| 午夜精品一区在线观看| 中文字幕第28页| 亚洲国产日韩a在线播放性色| 激情视频在线播放| 亚洲午夜精品网| 久久精品免费av| 亚洲成av人片在线| 青草视频在线观看免费| 色综合久久久久综合99| 亚洲GV成人无码久久精品| 91福利精品第一导航| 中文字幕av第一页| 欧美日韩dvd在线观看| 一本到在线视频| 欧美大肚乱孕交hd孕妇| 亚洲老妇色熟女老太| 亚洲精品国精品久久99热 | 另类美女黄大片| 美女91在线| 欧美一级电影久久| 日产精品一区| 91免费综合在线| 97人人澡人人爽91综合色| 精品一区二区三区视频日产| 国产精品入口久久| 在线码字幕一区| 伊人久久大香线蕉综合热线| av片中文字幕| 精品一区二区精品| 99久久久无码国产精品性波多| 99久久精品国产一区| 免费看91的网站| 亚洲精品国产一区二区精华液 | 久久综合亚州| 国产在线观看中文字幕| 成人av午夜电影| 天天舔天天操天天干| 一区二区三区不卡视频 | 欧美一区二区三区四区五区| 隣の若妻さん波多野结衣| 精品亚洲一区二区三区| 色欧美激情视频在线| 久久人91精品久久久久久不卡| 欧美专区福利免费| 51精品国产人成在线观看| 国产成人高清| 黄色激情在线视频| 毛片不卡一区二区| 在线xxxxx| 亚洲欧洲av色图| 国产成人免费看| 91精品国产免费| 黄色小视频在线免费观看| 欧美成人免费大片| 久久精品国产精品亚洲毛片| 精品国产一区二区三区久久久久久| 日韩系列欧美系列| 亚洲午夜无码av毛片久久| 国产一区二区三区美女| 亚洲AV无码片久久精品| 一区二区高清视频在线观看| 中文天堂在线播放| 国产视频精品免费播放| 亚洲wwwww| 成人乱人伦精品视频在线观看| 亚洲人成网亚洲欧洲无码| 国产午夜精品视频一区二区三区| 首页亚洲欧美制服丝腿| 影音先锋人妻啪啪av资源网站| 成人欧美一区二区三区小说| 五月婷婷激情五月| 日韩精品欧美激情| 黄色小说在线播放| 91麻豆蜜桃| 91精品国产91久久久久久密臀 | 国产麻豆一区| 欧美极品一区二区| 一区二区福利| 久久久午夜精品福利内容| 一区二区国产视频| jlzzjlzz亚洲女人18| 另类天堂视频在线观看| 欧美黄色a视频| 亚洲欧美日产图| 日本不卡高清视频| 日韩人妻无码精品综合区| 欧美日韩性视频在线| 天天爱天天干天天操| 久久久久九九九九| 成人在线视频中文字幕| 青春草国产视频| 成人免费视频播放| 日本系列第一页| 亚洲国产精品久久精品怡红院| 欧美xxxx性xxxxx高清| aaa级精品久久久国产片| 欧美91视频| 亚洲欧美综合视频| 亚洲一二三四区不卡| 可以免费观看的毛片| 午夜精品一区二区三区在线视频 | 美女色狠狠久久| 天堂资源在线亚洲视频| 青青青爽久久午夜综合久久午夜 | 久久香蕉国产| 不卡的av中文字幕| 亚洲人成在线播放网站岛国| 国产精品一区二区av白丝下载 | 日韩一区二区高清视频| 国产99一区视频免费| 日本在线视频中文字幕| 日韩av在线一区二区| 性欧美1819sex性高清| 日韩精品一线二线三线| 蜜桃av噜噜一区二区三区小说| 国产精品综合激情| 欧美久久婷婷综合色| av免费在线观看网站| 国产一级二级三级精品| 免费日韩av片| 黄色国产在线播放| 91精品在线观看入口| a天堂资源在线| 欧美日韩在线观看一区| 久久电影网电视剧免费观看| 麻豆国产尤物av尤物在线观看| 精品国产不卡一区二区三区| 欧美xx视频| 国产精品99久久久久久大便| 国产91精品欧美| 人妻丰满熟妇av无码区| 中文字幕亚洲二区| 日本免费一区二区三区视频| 国产精品999视频| 国产精品视频一二三| 亚洲欧美另类日韩| 国产成人中文字幕| 中文字幕一区二区三区乱码图片| 久久久午夜精品福利内容| 欧美色视频一区| 国产高清在线a视频大全| 青青草久久网络| 成人午夜碰碰视频| 久久精品99北条麻妃| 欧美激情精品久久久久久免费印度| 美女亚洲一区| 日本wwwwwww| 欧美性大战久久| 黄色激情在线播放| 伊人久久99| 91日韩精品一区| www.热久久| 国产精品色婷婷视频| 99人久久精品视频最新地址| 美国精品一区二区|