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

ThreadLocal全攻略:使用實(shí)戰(zhàn),源碼分析,內(nèi)存泄露分析

存儲(chǔ) 存儲(chǔ)軟件
本篇文章我們從ThreadLocal的使用場(chǎng)景、源碼、類(lèi)結(jié)構(gòu)、內(nèi)存結(jié)構(gòu)等進(jìn)行分析說(shuō)明,最后分析了其引起內(nèi)存泄露的根本原因。

[[395368]]

前言

說(shuō)起ThreadLocal即便你沒(méi)有直接用到過(guò),它也間接的出現(xiàn)在你使用過(guò)的框架里,比如Spring的事物管理,Hibernate的Session管理、logback(和log4j)中的MDC功能實(shí)現(xiàn)等。而在項(xiàng)目開(kāi)發(fā)中,比如用到的一些分頁(yè)功能的實(shí)現(xiàn)往往也會(huì)借助于ThreadLocal。

正是因?yàn)門(mén)hreadLocal的無(wú)處不在,所以在面試的時(shí)候也經(jīng)常會(huì)被問(wèn)到它的實(shí)現(xiàn)原理、核心API使用以及內(nèi)存泄露的問(wèn)題。

而且基于這些問(wèn)題還可以拓展到線程安全方面、JVM內(nèi)存管理與分析、Hash算法等等知識(shí)點(diǎn)。可見(jiàn)ThreadLocal對(duì)開(kāi)發(fā)人員來(lái)說(shuō)是多么的重要的。如果你還沒(méi)有全面的了解,那么這篇文章值得你深入學(xué)習(xí)一下。

什么是ThreadLocal

ThreadLocal是Therad的局部變量的維護(hù)類(lèi),在Java中是作為一個(gè)特殊的變量存儲(chǔ)在。當(dāng)使用ThreadLocal維護(hù)變量時(shí),ThreadLocal為每個(gè)使用該變量的線程提供獨(dú)立的變量副本,所以每一個(gè)線程都可以獨(dú)立地改變自己的副本,而不會(huì)影響其它線程所對(duì)應(yīng)的副本。

因?yàn)槊總€(gè)Thread內(nèi)有自己的實(shí)例副本,且該副本只能由當(dāng)前Thread使用,也就不存在多線程間共享的問(wèn)題。

總的來(lái)說(shuō),ThreadLocal適用于每個(gè)線程需要自己獨(dú)立的實(shí)例且該實(shí)例需要在多個(gè)方法中被使用,也即變量在線程間隔離而在方法或類(lèi)間共享的場(chǎng)景。

比如,有一個(gè)變量count,在多線程并發(fā)時(shí)操作count++會(huì)出現(xiàn)線程安全問(wèn)題。但是通過(guò)ThreadLocal就可以為每個(gè)線程創(chuàng)建只屬于當(dāng)前線程的count副本,各自操作各自的副本,不會(huì)影響到其他線程。

從另外一個(gè)角度來(lái)說(shuō),ThreadLocal是一個(gè)數(shù)據(jù)結(jié)構(gòu),有點(diǎn)像HashMap,可以保存"key:value"鍵值對(duì),但是一個(gè)ThreadLocal只能保存一個(gè)鍵值對(duì),各個(gè)線程的數(shù)據(jù)互不干擾。

  1. @Test 
  2. public void test1(){ 
  3.     ThreadLocal<String> localName = new ThreadLocal<>(); 
  4.     // 只提供了一個(gè)set方法; 
  5.     localName.set("程序新視界"); 
  6.     // 同時(shí)只提供了一個(gè)get方法 
  7.     String name = localName.get(); 
  8.     System.out.println(name); 

上述代碼中線程A初始化了一個(gè)ThreadLocal對(duì)象,并調(diào)用set方法,保持了一個(gè)值。而這個(gè)值只能線程A調(diào)用get方法才能獲取到。如果此時(shí)線程B調(diào)用get方法是無(wú)法獲取到的。至于如何實(shí)現(xiàn)這一功能的,我們?cè)诤竺嬖创a分析中進(jìn)行講解,這里知道其功能即可。

ThreadLocal使用實(shí)例

上面介紹了使用場(chǎng)景和基本的實(shí)現(xiàn)理論,下面我們就來(lái)通過(guò)一個(gè)簡(jiǎn)單的實(shí)例看一下如何使用ThreadLocal。

  1. public class ThreadLocalMain { 
  2.  
  3.     /** 
  4.      * ThreadLocal變量,每個(gè)線程都有一個(gè)副本,互不干擾 
  5.      */ 
  6.     public static final ThreadLocal<String> HOLDER = new ThreadLocal<>(); 
  7.  
  8.     public static void main(String[] args) throws Exception { 
  9.         new ThreadLocalMain().execute(); 
  10.     } 
  11.  
  12.     public void execute() throws Exception { 
  13.         // 主線程設(shè)置值 
  14.         HOLDER.set("程序新視界"); 
  15.         System.out.println(Thread.currentThread().getName() + "線程ThreadLocal中的值:" + HOLDER.get()); 
  16.  
  17.         new Thread(() -> { 
  18.             System.out.println(Thread.currentThread().getName() + "線程ThreadLocal中的值:" + HOLDER.get()); 
  19.             // 設(shè)置當(dāng)前線程中的值 
  20.             HOLDER.set("《程序新視界》"); 
  21.             System.out.println("重新設(shè)置之后," + Thread.currentThread().getName() + "線程ThreadLocal中的值:" + HOLDER.get()); 
  22.             System.out.println(Thread.currentThread().getName() + "線程執(zhí)行結(jié)束"); 
  23.         }).start(); 
  24.         // 等待所有線程執(zhí)行結(jié)束 
  25.         Thread.sleep(1000L); 
  26.         System.out.println(Thread.currentThread().getName() + "線程ThreadLocal中的值:" + HOLDER.get()); 
  27.     } 
  28.  

示例中定義了一個(gè)static final的ThreadLocal變量HOLDER,在main方法中模擬通過(guò)兩個(gè)線程來(lái)操作HOLDER中存儲(chǔ)的值。先對(duì)HOLDER設(shè)置一個(gè)值,然后打印獲取得到的值,然后新起一個(gè)線程去修改HOLDER中的值,然后分別在新線程和主線程兩處獲取對(duì)應(yīng)的值。

執(zhí)行程序,打印結(jié)果如下:

  1. main線程ThreadLocal中的值:程序新視界 
  2. Thread-0線程ThreadLocal中的值:null 
  3. 重新設(shè)置之后,Thread-0線程ThreadLocal中的值:《程序新視界》 
  4. Thread-0線程執(zhí)行結(jié)束 
  5. main線程ThreadLocal中的值:程序新視界 

對(duì)照程序和輸出結(jié)果,你會(huì)發(fā)現(xiàn),主線程和Thread-0各自獨(dú)享自己的變量存儲(chǔ)。主線程并沒(méi)有因?yàn)門(mén)hread-0調(diào)用了HOLDER的set方法而被改變。

之所以能達(dá)到這個(gè)效果,正是因?yàn)樵赥hreadLocal中,每個(gè)線程Thread擁有一份自己的副本變量,多個(gè)線程互不干擾。那么,你會(huì)疑惑,ThreadLocal是如何實(shí)現(xiàn)這一功能的呢?

ThreadLocal原理分析

在學(xué)習(xí)ThreadLocal的原理之前,我們先來(lái)看一些相關(guān)的理論知識(shí)和數(shù)據(jù)結(jié)構(gòu)。

基本流程與源碼實(shí)現(xiàn)

一個(gè)線程內(nèi)可以存多個(gè)ThreadLocal對(duì)象,存儲(chǔ)的位置位于Thread的ThreadLocal.ThreadLocalMap變量,在Thread中有如下變量:

  1. /* ThreadLocal values pertaining to this thread. This map is maintained 
  2.  * by the ThreadLocal class. */ 
  3. ThreadLocal.ThreadLocalMap threadLocals = null

ThreadLocalMap是由ThreadLocal維護(hù)的靜態(tài)內(nèi)部類(lèi),正如代碼中注解所說(shuō)這個(gè)變量是由ThreadLocal維護(hù)的。

我們?cè)谑褂肨hreadLocal的get()、set()方法時(shí),其實(shí)都是調(diào)用了ThreadLocalMap類(lèi)對(duì)應(yīng)的get()、set()方法。

Thread中的這個(gè)變量的初始化通常是在首次調(diào)用ThreadLocal的get()、set()方法時(shí)進(jìn)行的。

  1. public void set(T value) { 
  2.     Thread t = Thread.currentThread(); 
  3.     ThreadLocalMap map = getMap(t); 
  4.     if (map != null
  5.         map.set(this, value); 
  6.     else 
  7.         createMap(t, value); 

上述set方法中,首先獲取當(dāng)前線程對(duì)象,然后通過(guò)getMap方法來(lái)獲取當(dāng)前線程中的threadLocals:

  1. ThreadLocalMap getMap(Thread t) { 
  2.     return t.threadLocals; 

如果Thread中的對(duì)應(yīng)屬性為null,則創(chuàng)建一個(gè)ThreadLocalMap并賦值給Thread:

  1. void createMap(Thread t, T firstValue) { 
  2.     t.threadLocals = new ThreadLocalMap(this, firstValue); 

如果已經(jīng)存在,則通過(guò)ThreadLocalMap的set方法設(shè)置值,這里我們可以看到set中key為this,也就是當(dāng)前ThreadLocal對(duì)象,而value值則是我們要存的值。

對(duì)應(yīng)的get方法源碼如下:

  1. public T get() { 
  2.     Thread t = Thread.currentThread(); 
  3.     ThreadLocalMap map = getMap(t); 
  4.     if (map != null) { 
  5.         ThreadLocalMap.Entry e = map.getEntry(this); 
  6.         if (e != null) { 
  7.             @SuppressWarnings("unchecked"
  8.             T result = (T)e.value; 
  9.             return result; 
  10.         } 
  11.     } 
  12.     return setInitialValue(); 

可以看到同樣通過(guò)當(dāng)前線程,拿到當(dāng)前線程的threadLocals屬性,然后從中獲取存儲(chǔ)的值并返回。在get的時(shí)候,如果Thread中的threadLocals屬性未進(jìn)行初始化,則也會(huì)間接調(diào)用createMap方法進(jìn)行初始化操作。

下面我們通過(guò)一個(gè)流程圖來(lái)匯總一下上述流程:

上述流程中給Thread的threadLocals屬性初始化的操作,在JDK8和9中通過(guò)debug發(fā)現(xiàn),都沒(méi)有走createMap方法,暫時(shí)還不清楚JVM是如何進(jìn)行初始化賦值的。而在測(cè)試JDK13和JDK14的時(shí)候,很明顯走了createMap方法。

ThreadLoalMap的數(shù)據(jù)結(jié)構(gòu)

ThreadLoalMap是ThreadLocal中的一個(gè)靜態(tài)內(nèi)部類(lèi),類(lèi)似HashMap的數(shù)據(jù)結(jié)構(gòu),但并沒(méi)有實(shí)現(xiàn)Map接口。

ThreadLoalMap中初始化了一個(gè)大小16的Entry數(shù)組,Entry對(duì)象用來(lái)保存每一個(gè)key-value鍵值對(duì)。通過(guò)上面的set方法,我們已經(jīng)知道其中的key永遠(yuǎn)都是ThreadLocal對(duì)象。

看一下相關(guān)的源碼:

  1. static class ThreadLocalMap { 
  2.  
  3.     static class Entry extends WeakReference<ThreadLocal<?>> { 
  4.         /** The value associated with this ThreadLocal. */ 
  5.         Object value; 
  6.  
  7.         Entry(ThreadLocal<?> k, Object v) { 
  8.             super(k); 
  9.             value = v; 
  10.         } 
  11.     } 
  12.  
  13.     private static final int INITIAL_CAPACITY = 16; 
  14.  
  15.     // ... 

ThreadLoalMap的類(lèi)圖結(jié)構(gòu)如下:

這里需要留意的是,ThreadLocalMap類(lèi)中的Entry對(duì)象繼承自WeakReference,也就是說(shuō)它是弱引用。這里會(huì)出現(xiàn)內(nèi)存泄露的情況,后續(xù)會(huì)講到。

由于hreadLocalMaps是延遲創(chuàng)建的,因此在構(gòu)造時(shí)至少要?jiǎng)?chuàng)建一個(gè)Entry對(duì)象。這里可以從構(gòu)造方法中看到:

  1. ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) { 
  2.     table = new Entry[INITIAL_CAPACITY]; 
  3.     int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1); 
  4.     table[i] = new Entry(firstKey, firstValue); 
  5.     size = 1; 
  6.     setThreshold(INITIAL_CAPACITY); 

上述構(gòu)造方法,創(chuàng)建了一個(gè)默認(rèn)長(zhǎng)度為16的Entry數(shù)組,通過(guò)hashCode與length位運(yùn)算確定索引值i。而上面也提到,每個(gè)Thread都有一個(gè)ThreadLocalMap類(lèi)型的變量。

至此,結(jié)合Thread,我們可以看到整個(gè)數(shù)據(jù)模型如下:

hash沖突及解決

我們留意到構(gòu)造方法中Entry在table中存儲(chǔ)位置是通過(guò)hashcode算法獲得。每個(gè)ThreadLocal對(duì)象都有一個(gè)hash值threadLocalHashCode,每初始化一個(gè)ThreadLocal對(duì)象,hash值就增加一個(gè)固定的大小0x61c88647。

在向ThreadLocalMap中的Entry數(shù)值存儲(chǔ)Entry對(duì)象時(shí),會(huì)根據(jù)ThreadLocal對(duì)象的hash值,定位到table中的位置i。這里分三種情況:

  • 如果當(dāng)前位置為空的,直接將Entry存放在對(duì)應(yīng)位置;
  • 如果位置i已經(jīng)有值且這個(gè)Entry對(duì)象的key正好是即將設(shè)置的key,那么重新設(shè)置Entry中的value;
  • 如果位置i的Entry對(duì)象和即將設(shè)置的key沒(méi)關(guān)系,則尋找一個(gè)空位置;

計(jì)算hash值便會(huì)有hash沖突出現(xiàn),常見(jiàn)的解決方法有:再哈希法、開(kāi)放地址法、建立公共溢出區(qū)、鏈?zhǔn)降刂贩ǖ取?/p>

上面的流程可以看出這里采用的是開(kāi)放地址方法,如果當(dāng)前位置有值,就繼續(xù)尋找下一個(gè)位置,注意table[len-1]的下一個(gè)位置是table[0],就像是一個(gè)環(huán)形數(shù)組,所以也叫閉散列法。如果一直都找不到空位置就會(huì)出現(xiàn)死循環(huán),發(fā)生內(nèi)存溢出。當(dāng)然有擴(kuò)容機(jī)制,一般不會(huì)找不到空位置的。

ThreadLocal內(nèi)存泄露

ThreadLocal使用不當(dāng)可能會(huì)出現(xiàn)內(nèi)存泄露,進(jìn)而可能導(dǎo)致內(nèi)存溢出。下面我們就來(lái)分析一下內(nèi)存泄露的原因及相關(guān)設(shè)計(jì)思想。

內(nèi)存引用鏈路

根據(jù)前面對(duì)ThreadLocal的分析,得知每個(gè)Thread維護(hù)一個(gè)ThreadLocalMap,它key是ThreadLocal實(shí)例本身,value是業(yè)務(wù)需要存儲(chǔ)的Object。也就是說(shuō)ThreadLocal本身并不存儲(chǔ)值,它只是作為一個(gè)key來(lái)讓線程從ThreadLocalMap獲取value。

仔細(xì)觀察ThreadLocalMap,這個(gè)map是使用ThreadLocal的弱引用作為Key的,弱引用的對(duì)象在GC時(shí)會(huì)被回收。因此使用了ThreadLocal后,引用鏈如圖所示:

其中虛線表示弱引用。下面我們先來(lái)了解一下Java中引用的分類(lèi)。

Java中的引用

Java中通常會(huì)存在以下類(lèi)型的引用:強(qiáng)引用、弱引用、軟引用、虛引用。

  • 強(qiáng)引用:通常new出來(lái)的對(duì)象就是強(qiáng)引用類(lèi)型,只要引用存在,垃圾回收器將永遠(yuǎn)不會(huì)回收被引用的對(duì)象,哪怕內(nèi)存不足的時(shí)候;
  • 軟引用:使用SoftReference修飾的對(duì)象被稱(chēng)為軟引用,軟引用指向的對(duì)象在內(nèi)存要溢出的時(shí)候被回收。如果回收之后,還沒(méi)有足夠的內(nèi)存,才會(huì)拋出內(nèi)存溢出異常;
  • 弱引用:使用WeakReference修飾的對(duì)象被稱(chēng)為弱引用,只要發(fā)生垃圾回收,無(wú)論當(dāng)前內(nèi)存是否足夠,都會(huì)回收掉只被弱引用關(guān)聯(lián)的對(duì)象實(shí)例。
  • 虛引用:虛引用是最弱的引用,在Java中使用PhantomReference進(jìn)行定義。虛引用中唯一的作用就是用隊(duì)列接收對(duì)象即將死亡的通知。

泄露原因分析

正常來(lái)說(shuō),當(dāng)Thread執(zhí)行完會(huì)被銷(xiāo)毀,Thread.threadLocals指向的ThreadLocalMap實(shí)例也隨之變?yōu)槔锩娲娣诺腅ntity也會(huì)被回收。這種情況是不會(huì)發(fā)生內(nèi)存泄漏的。

發(fā)生內(nèi)存泄露的場(chǎng)景一般存在于線程池的情況下。此時(shí),Thread生命周期比較長(zhǎng)(存在循環(huán)使用),threadLocals引用一直存在,當(dāng)其存放的ThreadLocal被回收(弱引用生命周期比較短)后,對(duì)應(yīng)的Entity就成了key為null的實(shí)例,但value值不會(huì)被回收。如果此Entity一直不被get()、set()、remove(),就一直不會(huì)被回收,也就發(fā)生了內(nèi)存泄漏。

所以,通常在使用完ThreadLocal后需要調(diào)用remove()方法進(jìn)行內(nèi)存的清除。

比如在web請(qǐng)求當(dāng)中,我們可以通過(guò)過(guò)濾器等進(jìn)行回收方法的調(diào)用:

  1. public void doFilter(ServeletRequest request, ServletResponse){ 
  2.     try{ 
  3.         //設(shè)置ThreadLocal變量 
  4.         localName.set("程序新視界"); 
  5.         chain.doFilter(request, response) 
  6.     }finally{ 
  7.         //調(diào)用remove方法溢出threadLocal中的變量 
  8.         localName.remove(); 
  9.     } 

為什么使用弱引用而不是強(qiáng)引用?

從表面上看內(nèi)存泄漏的根源在于使用了弱引用,但為什么JDK采用了弱引用的實(shí)現(xiàn)而不是強(qiáng)引用呢?

先來(lái)看ThreadLocalMap類(lèi)上的一段注釋?zhuān)?/p>

  1. To help deal with very large and long-lived usages, the hash table entries use WeakReferences for keys.  
  2.  
  3. 為了協(xié)助處理數(shù)據(jù)比較大并且生命周期比較長(zhǎng)的場(chǎng)景,hash table的條目使用了WeakReference作為key。 

為了協(xié)助處理數(shù)據(jù)比較大并且生命周期比較長(zhǎng)的場(chǎng)景,hash table的條目使用了WeakReference作為key。

這跟我們想象的有些不同,弱引用反而是為了解決內(nèi)存存儲(chǔ)問(wèn)題而專(zhuān)門(mén)使用的。

我們先來(lái)假設(shè)一下,如果key使用強(qiáng)引用,那么在其他持有ThreadLocal引用的對(duì)象都回收了,但ThreadLocalMap依舊持有ThreadLocal的強(qiáng)引用,這就導(dǎo)致ThreadLocal不會(huì)被回收,從而導(dǎo)致Entry內(nèi)存泄露。

對(duì)照一下,弱引用的情況。持有ThreadLocal引用的對(duì)象都回收了,ThreadLocalMap持有的是ThreadLocal的弱引用,會(huì)被自動(dòng)回收。只不過(guò)對(duì)應(yīng)的value值,需要在下次調(diào)用set/get/remove方法時(shí)會(huì)被清除。

綜合對(duì)比會(huì)發(fā)現(xiàn),采用弱引用反而多了一層保障,ThreadLocal被清理后key為null,對(duì)應(yīng)的value在下一次ThreadLocalMap調(diào)用set、get、remove的時(shí)候可能會(huì)被清除。

所以,內(nèi)存泄露的根本原因是是否手動(dòng)清除操作,而不是弱引用。

ThreadLocal應(yīng)用場(chǎng)景

最后,我們?cè)賮?lái)回顧一下ThreadLocal的應(yīng)用場(chǎng)景:

  • 線程間數(shù)據(jù)隔離,各線程的ThreadLocal互不影響;
  • 方便同一個(gè)線程使用某一對(duì)象,避免不必要的參數(shù)傳遞;
  • 全鏈路追蹤中的traceId或者流程引擎中上下文的傳遞一般采用ThreadLocal;
  • Spring事務(wù)管理器采用了ThreadLocal;
  • Spring MVC的RequestContextHolder的實(shí)現(xiàn)使用了ThreadLocal;

小結(jié)

本篇文章我們從ThreadLocal的使用場(chǎng)景、源碼、類(lèi)結(jié)構(gòu)、內(nèi)存結(jié)構(gòu)等進(jìn)行分析說(shuō)明,最后分析了其引起內(nèi)存泄露的根本原因。通過(guò)本篇文章的學(xué)習(xí),基本上能掌握ThreadLocal百分之百九十的核心知識(shí)點(diǎn)。你學(xué)到了嗎?

 

責(zé)任編輯:武曉燕 來(lái)源: 程序新視界
相關(guān)推薦

2024-10-31 09:24:42

2022-10-21 11:30:42

用戶生命周期分析

2013-06-08 11:13:00

Android開(kāi)發(fā)XML解析

2009-02-20 11:43:22

UNIXfish全攻略

2025-04-02 09:33:01

2025-06-26 05:00:00

2023-05-29 07:17:48

內(nèi)存溢出場(chǎng)景

2009-07-17 17:43:49

Jruby開(kāi)發(fā)Web

2010-04-23 14:04:23

Oracle日期操作

2024-05-07 09:01:21

Queue 模塊Python線程安全隊(duì)列

2013-04-15 10:48:16

Xcode ARC詳解iOS ARC使用

2023-10-13 19:42:00

2025-05-28 08:45:00

2009-07-04 11:05:48

Linux安全攻略

2009-10-19 15:20:01

家庭綜合布線

2009-12-14 14:32:38

動(dòng)態(tài)路由配置

2014-03-19 17:22:33

2021-01-29 17:40:00

Flyme安卓手機(jī)安全

2011-07-19 20:36:56

2018-10-25 15:24:10

ThreadLocal內(nèi)存泄漏Java
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

精品88久久久久88久久久| 国产乱子伦一区二区三区国色天香| 精品国产百合女同互慰| 116极品美女午夜一级| 97超碰人人在线| 国产精品456露脸| 欧美做爰性生交视频| 少妇高潮一区二区三区喷水| 97品白浆高清久久久久久| 一本色道综合亚洲| 免费cad大片在线观看| 日韩精品视频无播放器在线看| 久久爱另类一区二区小说| 久久久影视精品| 美国黄色片视频| 色狼人综合干| 日韩欧美亚洲国产另类| 成人免费视频久久| 123区在线| 亚洲日本护士毛茸茸| 久久99精品久久久久久三级 | 成人h视频在线观看| 无码人妻av一区二区三区波多野| 牛牛国产精品| 在线播放精品一区二区三区| 国产激情视频网站| 亚洲精品国产九九九| 欧美日韩在线综合| 国产黄视频在线| 国产极品人妖在线观看| 日本天码aⅴ片在线电影网站| 国产乱淫片视频| 视频二区一区| 亚洲综合欧美在线| 爱情岛亚洲播放路线| 国产视频一区在线播放| 国产精品白丝jk白祙| 亚洲无码精品在线播放| 久久九九国产| 91成人国产在线观看| 久久久美女视频| 一区二区三区网站| 精品国产一区二区三区久久久狼 | 中文另类视频| 色综合久久天天综合网| 亚洲熟妇av一区二区三区漫画| 亚洲妇熟xxxx妇色黄| 亚洲视频 欧洲视频| 亚洲一区二区不卡视频| a视频网址在线观看| 久久久国产午夜精品| 欧美二区三区| 国产三级在线| 国产人久久人人人人爽| 日本亚洲欧洲精品| av在线电影观看| 欧美国产日产图区| 亚洲视频电影| 国产三区视频在线观看| 亚洲欧美日韩精品久久久久| 五月天色婷婷综合| 99热国产在线| 亚洲高清久久久| 91国视频在线| 亚洲a∨精品一区二区三区导航| 日本精品一区二区三区高清 | 91麻豆精品| 91精品麻豆日日躁夜夜躁| 中文字幕55页| 免费黄色一级大片| 黄色av电影在线播放| 欧美国产日韩亚洲一区| 亚洲电影一二三区| 精品一区二区三孕妇视频| 伊人成综合网伊人222| 亚洲欧洲日产国码av系列天堂| 爱爱免费小视频| 欧美中文字幕一区二区| 久久影院资源网| 久久精品国产亚洲av高清色欲| 亚洲美女一区| 国产精品九九久久久久久久| 国产精品热久久| www.一区二区| 亚洲 国产 日韩 综合一区| 乱人伦中文视频在线| 亚洲欧美日韩国产成人精品影院| r级无码视频在线观看| 范冰冰一级做a爰片久久毛片| 91久久精品一区二区三区| 亚洲天堂伊人网| 久久影院资源站| 中文字幕日韩av| 国产精品23p| 麻豆精品在线播放| 国产伦理一区二区三区| yiren22亚洲综合伊人22| 一区二区理论电影在线观看| 国产免费视频传媒| 伊人久久亚洲| 在线日韩日本国产亚洲| 69精品久久久| 久久精品国产第一区二区三区| 操一操视频一区| 爱爱爱免费视频在线观看| 亚洲综合区在线| 污污网站免费看| 秋霞综合在线视频| 久久九九国产精品怡红院 | 岛国成人毛片| 欧美日韩亚洲一区二区| 久国产精品视频| 九九热爱视频精品视频| 成人福利视频网站| 亚洲精品电影久久久| 超碰人人人人人人人| 亚洲激情婷婷| 亚洲va欧美va国产综合剧情| www在线播放| 欧美日韩一区二区免费在线观看 | 岛国精品一区| 丝袜亚洲另类欧美重口| 欧美一级特黄视频| 国产成人精品三级麻豆| 亚洲一区3d动漫同人无遮挡 | 性色一区二区三区| 成人资源视频网站免费| 免费**毛片在线| 91豆麻精品91久久久久久| 国产激情视频网站| 在线成人亚洲| 国产精品福利视频| 欧美卡一卡二| 日韩美女视频在线| 视频这里只有精品| 精品在线观看免费| 亚洲一区二区三区午夜| 色猫猫成人app| 国产午夜精品一区理论片飘花 | 久久精品免费| 欧美精品v日韩精品v国产精品| 男人av在线播放| 亚洲精品一区二区三区影院| 黄色一级视频免费观看| 国产福利一区二区三区在线视频| 一区二区三区日韩视频| 亚洲精品555| 中文字幕日韩免费视频| www.亚洲激情| 国产精品三级视频| 亚洲一区日韩精品| 欧美残忍xxxx极端| 91九色精品视频| 国产色在线观看| 日韩网站在线看片你懂的| 天天操天天操天天操天天操天天操| 国产主播一区二区三区| 日韩一区日韩二区| 一区二区成人网| 第一会所亚洲原创| 成人久久久久久久| 91国内在线| 欧美精品一区二区在线播放 | 一级毛片视频在线| 欧美精品1区2区| 国产精品老熟女一区二区| 成人午夜视频免费看| 久久国产亚洲精品无码| 自拍自偷一区二区三区| 国产精品美女www| 大地资源网3页在线观看| 欧美成人猛片aaaaaaa| 日本视频免费在线| 国产欧美一区二区精品性色超碰 | 麻豆精品久久久久久久99蜜桃| 国产午夜精品在线观看| 国产无色aaa| 激情欧美国产欧美| 日本一区二区在线| 久久影院一区二区三区| 国内免费久久久久久久久久久| 日本不卡免费播放| 在线成人午夜影院| 日韩高清免费av| 中文字幕av不卡| wwwxxx色| 日韩和欧美一区二区三区| 日韩 欧美 自拍| 免费福利视频一区| 成人激情在线播放| 蜜桃麻豆av在线| 中文字幕亚洲专区| 手机看片一区二区三区| 欧美日韩国产一区| 日本少妇做爰全过程毛片| 亚洲国产精品成人综合| 国产精久久久久| 免费在线成人网| 91丨porny丨探花| 久久国产精品亚洲人一区二区三区| 99精品国产高清一区二区| 日本一区二区三区视频在线| 高清亚洲成在人网站天堂| 在线免费观看黄| 亚洲福利在线看| 国产女18毛片多18精品| 欧美自拍偷拍一区| 日韩av在线播| 伊人婷婷欧美激情| 肥熟一91porny丨九色丨| 在线观看美女av| av资源网一区| 色婷婷一区二区三区在线观看| 性欧美长视频| 婷婷五月综合缴情在线视频| 99精品全国免费观看视频软件| 麻豆亚洲一区| 91在线一区| 成人妇女淫片aaaa视频| 欧美暴力调教| 欧美在线一区二区视频| 91九色在线播放| 久久99久久久久久久噜噜| 黄色片在线看| 日韩大片在线观看视频| 亚洲第一视频在线播放| 欧美一区二区三区影视| 中文字幕日韩国产| 91久久精品午夜一区二区| 亚洲黄色一区二区| 亚洲最快最全在线视频| 亚洲精品电影院| 国产亚洲一区二区在线观看| 亚洲精品乱码久久| 成人福利在线看| 中文字幕永久免费| 紧缚奴在线一区二区三区| 国模无码视频一区二区三区| 国色天香一区二区| 激情五月婷婷六月| 牛牛国产精品| 成人在线免费观看视频网站| 综合久久婷婷| 992tv快乐视频| 欧美一区网站| 久久av综合网| 亚洲高清毛片| 久色视频在线播放| 亚洲一区网站| 麻豆av免费在线| 日韩专区中文字幕一区二区| 久久久久久久久久久久久久国产| 噜噜噜躁狠狠躁狠狠精品视频| 9久久9毛片又大又硬又粗| 亚洲精品综合| 亚洲色成人一区二区三区小说| 国产视频亚洲| 日韩免费高清在线| 日本美女一区二区三区视频| 污色网站在线观看| 精品亚洲porn| 师生出轨h灌满了1v1| 从欧美一区二区三区| 先锋资源av在线| 久久久www成人免费毛片麻豆 | 国产剧情久久久| 日韩视频国产视频| 日本精品999| 亚洲免费中文字幕| 自拍视频在线| 久久999免费视频| aa视频在线观看| 国产成人精品免费视频| 色诱色偷偷久久综合| 99三级在线| 国产成人手机高清在线观看网站| 午夜精品区一区二区三| 在线观看免费一区二区| 青青草国产精品视频| 热久久免费视频| 成人高清在线观看视频| 92精品国产成人观看免费| 精品熟妇无码av免费久久| 一区二区三区日韩在线观看| 色一情一乱一伦| 欧美一区二区视频网站| 天堂av资源在线| 日韩一二三在线视频播| 91福利在线免费| 国产剧情久久久久久| 高潮久久久久久久久久久久久久| 欧美日韩亚洲一区二区三区四区| 97在线精品| 免费无码不卡视频在线观看| 美女在线观看视频一区二区| 成人午夜精品无码区| 国产精品美女久久福利网站| 日韩欧美亚洲一区二区三区| 欧洲在线/亚洲| 免费观看黄一级视频| 日日摸夜夜添一区| 男人久久天堂| 97久草视频| 色狮一区二区三区四区视频| 99精品视频在线看| 国产成人久久精品77777最新版本| 亚洲一二三精品| 精品成人乱色一区二区| 国产免费不卡视频| 一区二区三区四区精品| av资源中文在线天堂| 亚洲一区二区三区sesese| 欧美精品尤物在线观看| 777精品久无码人妻蜜桃| 国产一区二区福利视频| 1024在线看片| 色婷婷久久99综合精品jk白丝| 欧美在线 | 亚洲| 欧美成人激情图片网| 巨大黑人极品videos精品| 欧美日韩系列| 噜噜噜久久亚洲精品国产品小说| www.四虎在线| 一区二区三区中文在线| 国产精品爽爽久久| 色吧影院999| 小明成人免费视频一区| 明星裸体视频一区二区| 亚洲激情婷婷| 少妇被狂c下部羞羞漫画| 亚洲综合免费观看高清完整版| 国产又粗又猛又爽又黄视频| 尤物99国产成人精品视频| 视频二区不卡| 日韩高清国产精品| 久久青草久久| 国产精品高清无码在线观看| 欧美日韩亚洲91| 天天操天天插天天射| 高清欧美性猛交xxxx黑人猛交| 国产精品17p| 日韩人妻无码精品久久久不卡| 国产丶欧美丶日本不卡视频| 青青操视频在线播放| 欧美一区二区三区在线| 日韩精品分区| 国产欧美综合精品一区二区| 亚洲国产黄色| 国产精品久久AV无码| 精品久久香蕉国产线看观看gif| 日本精品一区二区在线观看| 91精品国产乱码久久久久久久久 | 欧美另类一区二区| 日韩av在线不卡| 成人免费无遮挡| 色乱码一区二区三在线看| 美腿丝袜亚洲三区| 国产精品视频一区二区三| 日韩欧美国产麻豆| 波多野结衣久久| 免费成人看片网址| 琪琪一区二区三区| 国产av 一区二区三区| 精品国内二区三区| 伊人久久综合一区二区| 日韩性感在线| 狠狠色丁香九九婷婷综合五月| 鲁一鲁一鲁一鲁一色| h片在线观看网站| 亚洲免费在线视频一区 二区| 欧美视频在线第一页| 成人免费在线观看视频| 精品国精品国产| jizz亚洲少妇| 亚洲成av人片乱码色午夜| 日韩禁在线播放| 性感美女一区二区三区| 成人网页在线观看| 久久亚洲精品国产| 中文字幕亚洲自拍| av动漫精品一区二区| 免费高清在线观看免费| 国产精品你懂的在线| 亚洲国产成人一区二区| 日本免费一区二区三区视频观看| 四虎国产精品免费观看| 一区二区三区四区影院| 欧美伊人久久久久久久久影院 | 久久中文资源| 中文字幕第100页| 五月综合激情婷婷六月色窝| 成年午夜在线| 国产精品免费一区二区| 日韩国产精品91| 国产精品第56页| 亚洲视频国产视频| 日韩在线精品强乱中文字幕| 国语对白做受xxxxx在线中国| 亚洲精品一二三| jizz日韩|