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

如何正確的使用Java事件通知

開發 后端
通過實現觀察者模式來提供 Java 事件通知(Java event notification)似乎不是件什么難事兒,但這過程中也很容易就掉進一些陷阱。本文介紹了我自己在各種情形下,不小心制造的一些常見錯誤。

通過實現觀察者模式來提供 Java 事件通知(Java event notification)似乎不是件什么難事兒,但這過程中也很容易就掉進一些陷阱。本文介紹了我自己在各種情形下,不小心制造的一些常見錯誤。

[[130877]]

Java 事件通知

讓我們從一個最簡單的 Java Bean 開始,它叫StateHolder,里面封裝了一個私有的 int 型屬性 state 和常見的訪問方法:

 

  1. public class StateHolder { 
  2.   private int state; 
  3.   
  4.   public int getState() { 
  5.     return state; 
  6.   } 
  7.   
  8.   public void setState( int state ) { 
  9.     this.state = state; 
  10.   } 

 

現在假設我們決定要 Java bean 給已注冊的觀察者廣播一條 狀態已改變 事件。小菜一碟!!!定義一個最簡單的事件和監聽器簡直擼起袖子就來……

 

  1. // change event to broadcast 
  2.  
  3. public class StateEvent { 
  4.  
  5. public final int oldState; 
  6.  
  7. public final int newState; 
  8.  
  9. StateEvent( int oldState, int newState ) { 
  10.  
  11. this.oldState = oldState; 
  12.  
  13. this.newState = newState; 
  14.  
  15.  
  16.  
  17. // observer interface 
  18.  
  19. public interface StateListener { 
  20.  
  21. void stateChanged( StateEvent event ); 
  22.  

 

接下來,我們需要在 StateHolder 的實例里注冊 StatListeners。

 

  1. public class StateHolder { 
  2.  
  3. private final Set listeners = new HashSet<>(); 
  4.  
  5. [...] 
  6.  
  7. public void addStateListener( StateListener listener ) { 
  8.  
  9. listeners.add( listener ); 
  10.  
  11.  
  12. public void removeStateListener( StateListener listener ) { 
  13.  
  14. listeners.remove( listener ); 
  15.  
  16.  

 

***一個要點,需要調整一下StateHolder#setState這個方法,來確保每次狀態有變時發出的通知,都代表這個狀態真的相對于上次產生變化了:

 

  1. public void setState( int state ) { 
  2.  
  3. int oldState = this.state; 
  4.  
  5. this.state = state; 
  6.  
  7. if( oldState != state ) { 
  8.  
  9. broadcast( new StateEvent( oldState, state ) ); 
  10.  
  11.  
  12.  
  13. private void broadcast( StateEvent stateEvent ) { 
  14.  
  15. for( StateListener listener : listeners ) { 
  16.  
  17. listener.stateChanged( stateEvent ); 
  18.  
  19.  

 

搞定了!要的就是這些。為了顯得專(zhuang)業(bi)一點,我們可能還甚至為此實現了測試驅動,并為嚴密的代碼覆蓋率和那根表示測試通過的小綠條而洋洋自得。而且不管怎么樣,這不就是我從網上那些教程里面學來的寫法嗎?

那么問題來了:這個解決辦法是有缺陷的……

#p#

并發修改

像上面那樣寫 StateHolder 很容易遇到并發修改異常(ConcurrentModificationException),即使僅僅限制在一個單線程里面用也不例外。但究竟是誰導致了這個異常,它又為什么會發生呢?

 

  1. java.util.ConcurrentModificationException 
  2.  
  3. at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429
  4.  
  5. at java.util.HashMap$KeyIterator.next(HashMap.java:1453
  6.  
  7. at com.codeaffine.events.StateProvider.broadcast(StateProvider.java:60
  8.  
  9. at com.codeaffine.events.StateProvider.setState(StateProvider.java:55
  10.  
  11. at com.codeaffine.events.StateProvider.main(StateProvider.java:122

 

乍一看這個錯誤堆棧包含的信息,異常是由我們用到的一個 HashMap 的 Iterator 拋出的,可在我們的代碼里沒有用到任何的迭代器,不是嗎?好吧,其實我們用到了。要知道,寫在 broadcast 方法里的 for each 結構,實際上在編譯時是會被轉變成一個迭代循環的。

因為在事件廣播過程中,如果一個監聽器試圖從 StateHolder 實例里面把自己移除,就有可能導致 ConcurrentModificationException。所以比起在原先的數據結構上進行操作,有一個解決辦法就是我們可以在這組監聽器的快照(snapshot)上進行迭代循環。

這樣一來,“移除監聽器”這一操作就不會再干擾事件廣播機制了(但要注意的是通知還是會有輕微的語義變化,因為當 broadcast 方法被執行的時候,這樣的移除操作并不會被快照體現出來):

 

  1. private void broadcast( StateEvent stateEvent ) { 
  2.  
  3. Set snapshot = new HashSet<>( listeners ); 
  4.  
  5. for( StateListener listener : snapshot ) { 
  6.  
  7. listener.stateChanged( stateEvent ); 
  8.  
  9.  

 

但是,如果 StateHolder 被用在一個多線程的環境里呢?

#p#

同步

要再多線程的環境里使用 StateHolder ,它就必須是線程安全的。不過這也很容易實現,給我們類里面的每個方法加上 synchronized 就搞定了,不是嗎?

 

  1. public class StateHolder { 
  2.  
  3. public synchronized void addStateListener( StateListener listener ) { [...] 
  4.  
  5. public synchronized void removeStateListener( StateListener listener ) { [...] 
  6.  
  7. public synchronized int getState() { [...] 
  8.  
  9. public synchronized void setState( int state ) { [...] 

 

現在我們讀寫操作 一個 StateHolder 實例的時候都有了內置鎖(Intrinsic Lock) 做保證,這使得公有方法具有了原子性,也確保了正確的狀態對不同的線程都可見。任務完成!

才怪……盡管這樣的實現是線程安全的,但一旦程序要調用它,就需要承擔死鎖的風險。

設想一下如下這種情形:線程 A 改變了 StateHolder 的狀態 S,在向各個監聽器(listener)廣播這個狀態 S 的時候,線程 B 視圖訪問狀態 S ,然后被阻塞。如果 B 持有了一個對象的同步鎖,這個對象又是關于狀態 S的,并且本來是要廣播給眾多監聽器當中的某一個的,這種情況下我們就會遇到一個死鎖。

這就是為什么我們要縮小狀態訪問的同步性,在一個“保護通道”里面來廣播這個事件:

 

  1. public class StateHolder { 
  2.  
  3. private final Set listeners = new HashSet<>(); 
  4.  
  5. private int state; 
  6.  
  7. public void addStateListener( StateListener listener ) { 
  8.  
  9. synchronized( listeners ) { 
  10.  
  11. listeners.add( listener ); 
  12.  
  13.  
  14.  
  15. public void removeStateListener( StateListener listener ) { 
  16.  
  17. synchronized( listeners ) { 
  18.  
  19. listeners.remove( listener ); 
  20.  
  21.  
  22.  
  23. public int getState() { 
  24.  
  25. synchronized( listeners ) { 
  26.  
  27. return state; 
  28.  
  29.  
  30.  
  31. public void setState( int state ) { 
  32.  
  33. int oldState = this.state; 
  34.  
  35. synchronized( listeners ) { 
  36.  
  37. this.state = state; 
  38.  
  39.  
  40. if( oldState != state ) { 
  41.  
  42. broadcast( new StateEvent( oldState, state ) ); 
  43.  
  44.  
  45.  
  46. private void broadcast( StateEvent stateEvent ) { 
  47.  
  48. Set snapshot; 
  49.  
  50. synchronized( listeners ) { 
  51.  
  52. snapshot = new HashSet<>( listeners ); 
  53.  
  54.  
  55. for( StateListener listener : snapshot ) { 
  56.  
  57. listener.stateChanged( stateEvent ); 
  58.  
  59.  
  60.  

 

上面這段代碼是在之前的基礎上稍加改進來實現的,通過使用 Set 實例作為內部鎖來提供合適(但也有些過時)的同步性,監聽者的通知事件在保護塊之外發生,這樣就避免了一種死等的可能。

注意: 由于系統并發操作的天性,這個解決方案并不能保證變化通知按照他們產生的順序依次到達監聽器。如果觀察者一側對實際狀態的準確性有較高要求,可以考慮把 StateHolder 作為你事件對象的來源。

如果事件順序這在你的程序里顯得至關重要,有一個辦法就是可以考慮用一個線程安全的先入先出(FIFO)結構,連同監聽器的快照一起,在 setState 方法的保護塊里緩沖你的對象。只要 FIFO 結構不是空的,一個獨立的線程就可以從一個不受保護的區域塊里觸發實際事件(生產者-消費者模式),這樣理論上就可以不必冒著死鎖的危險還能確保一切按照時間順序進行。我說理論上,是因為到目前為止我也還沒親自這么試過。。

鑒于前面已經實現的,我們可以用諸如 CopyOnWriteArraySet 和 AtomicInteger 來寫我們的這個線程安全類,從而使這個解決方案不至于那么復雜:

 

  1. public class StateHolder { 
  2.  
  3. private final Set listeners = new CopyOnWriteArraySet<>(); 
  4.  
  5. private final AtomicInteger state = new AtomicInteger(); 
  6.  
  7. public void addStateListener( StateListener listener ) { 
  8.  
  9. listeners.add( listener ); 
  10.  
  11.  
  12. public void removeStateListener( StateListener listener ) { 
  13.  
  14. listeners.remove( listener ); 
  15.  
  16.  
  17. public int getState() { 
  18.  
  19. return state.get(); 
  20.  
  21.  
  22. public void setState( int state ) { 
  23.  
  24. int oldState = this.state.getAndSet( state ); 
  25.  
  26. if( oldState != state ) { 
  27.  
  28. broadcast( new StateEvent( oldState, state ) ); 
  29.  
  30.  
  31.  
  32. private void broadcast( StateEvent stateEvent ) { 
  33.  
  34. for( StateListener listener : listeners ) { 
  35.  
  36. listener.stateChanged( stateEvent ); 
  37.  
  38.  
  39.  

 

既然 CopyOnWriteArraySet 和 AtomicInteger 已經是線程安全的了,我們不再需要上面提到的那樣一個“保護塊”。但是等一下!我們剛剛不是在學到應該用一個快照來廣播事件,來替代用一個隱形的迭代器在原集合(Set)里面做循環嘛?

這或許有些繞腦子,但是由 CopyOnWriteArraySet 提供的 Iterator(迭代器)里面已經有了一個“快照“。CopyOnWriteXXX 這樣的集合就是被特別設計在這種情況下大顯身手的——它在小長度的場景下會很高效,而針對頻繁迭代和只有少量內容修改的場景也做了優化。這就意味著我們的代碼是安全的。

隨著 Java 8 的發布,broadcast 方法可以因為Iterable#forEach 和 lambdas表達式的結合使用而變得更加簡潔,代碼當然也是同樣安全,因為迭代依然表現為在“快照”中進行:

 

  1. private void broadcast( StateEvent stateEvent ) { 
  2.  
  3. listeners.forEach( listener -> listener.stateChanged( stateEvent ) ); 
  4.  

 

#p#

異常處理

本文的***介紹了如何處理拋出 RuntimeExceptions 的那些損壞的監聽器。盡管我總是嚴格對待 fail-fast 錯誤機制,但在這種情況下讓這個異常得不到處理是不合適的。尤其考慮到這種實現經常在一些多線程環境里被用到。

損壞的監聽器會有兩種方式來破壞系統:***,它會阻止通知向觀察者的傳達過程;第二,它會傷害那些沒有準備處理好這類問題的調用線程。總而言之它能夠導致多種莫名其妙的故障,并且有的還難以追溯其原因,

因此,把每一個通知區域用一個 try-catch 塊來保護起來會顯得比較有用。

 

  1. private void broadcast( StateEvent stateEvent ) { 
  2.  
  3. listeners.forEach( listener -> notifySafely( stateEvent, listener ) ); 
  4.  
  5.  
  6. private void notifySafely( StateEvent stateEvent, StateListener listener ) { 
  7.  
  8. try { 
  9.  
  10. listener.stateChanged( stateEvent ); 
  11.  
  12. catch( RuntimeException unexpected ) { 
  13.  
  14. // appropriate exception handling goes here... 
  15.  
  16.  

 

總結

綜上所述,Java 的事件通知里面有一些基本要點你還是必須得記住的。在事件通知過程中,要確保在監聽器集合的快照里做迭代,保證事件通知在同步塊之外,并且在合適的時候再安全地通知監聽器。

但愿我寫的這些讓你覺得通俗易懂,最起碼尤其在并發這一節不要再被搞得一頭霧水。如果你發現了文章中的錯誤或者有其它的點子想分享,盡管在文章下面的評論里告訴我吧。

責任編輯:王雪燕 來源: ImportNew
相關推薦

2019-11-14 16:23:07

MySQL索引數據庫

2010-02-03 15:40:37

Python函數

2017-10-31 20:45:07

JavaJava8Optional

2020-12-29 05:34:48

Scrapy網頁源代碼

2018-12-05 09:00:00

RedisRedis Strea數據庫

2022-09-07 08:58:58

Node.js框架

2009-01-19 09:40:53

JavaScript事件代理事件處理器

2010-05-12 15:00:50

MySQL事件

2010-07-07 10:25:00

SQL Server索

2010-01-18 17:23:55

函數

2021-03-15 12:23:24

Pythonyield代碼

2010-01-18 17:23:55

函數

2023-12-26 11:56:14

Go通道編程

2022-11-23 08:00:00

開發Regulator調試

2011-04-27 16:38:31

投影機

2014-04-09 09:32:24

Go并發

2015-08-05 09:33:21

Javawaitnotify

2017-08-30 17:47:35

MySql索引

2010-08-26 10:36:44

2020-08-19 08:39:05

中間件前端設計模式
點贊
收藏

51CTO技術棧公眾號

国产精品久久影院| 丝袜美腿高跟呻吟高潮一区| 欧美一级夜夜爽| 成年女人18级毛片毛片免费| 国产永久免费高清在线观看 | jizzjizzxxxx| 98在线视频| 粉嫩嫩av羞羞动漫久久久| 欧美一区二区三区免费视| 成年人二级毛片| 性欧美lx╳lx╳| 91精品中文字幕一区二区三区| 亚洲精品无码国产| 91精品大全| 不卡的电视剧免费网站有什么| 国产精品流白浆视频| 久久精品美女视频| 欧美xxxxx视频| 亚洲国产高清福利视频| 亚洲a级黄色片| 91av亚洲| 五月婷婷久久综合| 麻豆中文字幕在线观看| 久草福利在线| 99re视频这里只有精品| 91在线观看免费网站| 中文字幕免费观看| 在线日韩av| 久久久精品999| 四季av中文字幕| 老牛精品亚洲成av人片| 欧美一区二区国产| 成 人 黄 色 小说网站 s色| 成人爱爱网址| 精品国产91久久久| 欧美久久在线观看| 色呦呦在线播放| 亚洲欧洲一区二区在线播放| 日本不卡在线观看| 日本天堂影院在线视频| 成人丝袜高跟foot| 成人区精品一区二区| 国产毛片毛片毛片毛片毛片| 久色成人在线| 国产精品678| 亚洲 欧美 中文字幕| 亚洲欧美日本日韩| 久久久影视精品| 青青草原免费观看| 欧美日本在线| 欧美黑人性猛交| 久久午夜鲁丝片午夜精品| 亚洲第一天堂| 欧美成人免费播放| 国产大学生自拍| 亚洲一区二区| 欧美日韩高清区| 在线观看成人毛片| 欧美激情偷拍| 97久久久久久| 欧产日产国产69| 巨乳诱惑日韩免费av| 日韩av片免费在线观看| 亚洲天堂五月天| 麻豆国产欧美日韩综合精品二区| 国产精品久久久久免费a∨大胸| 中文字幕av无码一区二区三区| 久久精品国产在热久久| 91色p视频在线| 亚洲精华国产精华精华液网站| 成人av在线电影| 乱一区二区三区在线播放| 青青久在线视频| 国产精品乱码一区二三区小蝌蚪| 在线观看免费黄色片| 好吊日av在线| 精品久久久久久中文字幕一区奶水| 国产裸体舞一区二区三区| 国产一区二区主播在线| 7777精品伊人久久久大香线蕉的 | av电影一区二区| 任我爽在线视频精品一| 婷婷视频在线| 一区二区久久久| 国产福利视频在线播放| 国内自拍亚洲| 亚洲精品一线二线三线无人区| 性欧美13一14内谢| 99久久亚洲精品蜜臀| 欧美激情乱人伦一区| 蜜臀精品一区二区三区| 激情综合五月天| 国产一区二区精品免费| 日韩精品成人av| 亚洲成人动漫在线观看| 三年中国国语在线播放免费| 欧美特黄不卡| 国产亚洲视频中文字幕视频| 久久久夜色精品| 视频精品一区二区| 91欧美精品午夜性色福利在线| 熟妇人妻一区二区三区四区| 国产精品久久福利| 久久视频这里有精品| 欧美另类激情| 亚洲精品一区av在线播放| 日韩欧美综合视频| 视频在线在亚洲| 国产日韩久久| 免费网站成人| 欧美午夜精品久久久久久人妖 | 久久久青草青青国产亚洲免观| 欧美亚洲视频一区| 欧美国产大片| 亚洲成人精品视频| 污软件在线观看| 奇米777欧美一区二区| 国产一区免费观看| 中文在线观看免费| 欧美视频你懂的| 超碰97人人干| 99精品视频免费| 国产成人一区二区三区免费看| 欧美日韩在线看片| 91成人免费在线| 国产伦精品一区二区三区妓女| 综合视频在线| 91在线视频免费| 搞黄视频在线观看| 一本到一区二区三区| 国产成人精品无码片区在线| 你懂的视频一区二区| 成人免费网站在线看| 福利片在线观看| 色婷婷综合视频在线观看| 国产精品一级无码| 影音先锋成人在线电影| 91精品久久久久久久久中文字幕| 国产裸舞福利在线视频合集| 日本高清不卡在线观看| 欧美bbbbb性bbbbb视频| 国产深夜精品| 欧美精品亚洲| 韩国美女久久| 亚洲欧美日韩视频一区| 国产在线观看黄色| 91麻豆免费看片| 久久久久久久久久久视频| 女仆av观看一区| 97视频在线观看免费| 午夜小视频在线播放| 偷拍亚洲欧洲综合| v8888av| 久久亚洲一区| 日韩精品国内| 欧美激情福利| 色综合男人天堂| 国精产品一品二品国精品69xx| 亚洲国产一区二区视频| 黄色片视频免费观看| 中国女人久久久| 欧洲高清一区二区| 成人在线黄色| 久久亚洲精品中文字幕冲田杏梨 | 国产91精品一区二区| 免费在线黄网站| 欧美人妖视频| 国产精品v片在线观看不卡| 国产中文字幕在线视频| 欧美精品vⅰdeose4hd| 久草视频免费播放| av亚洲精华国产精华| 国产精品亚洲a| 日韩系列欧美系列| 北条麻妃高清一区| 色黄视频在线观看| 中文欧美日本在线资源| 97精品人妻一区二区三区香蕉 | 日韩a级在线观看| 台湾色综合娱乐中文网| 国产精品 欧美在线| 国产在线高清视频| 亚洲精品mp4| 在线视频1卡二卡三卡| 亚洲黄色av一区| 国产肥白大熟妇bbbb视频| 久久99久久久欧美国产| 131美女爱做视频| 日韩欧美大片| 国内一区二区三区在线视频| 亚洲成av在线| 欧美精品18videos性欧美| 九色视频成人自拍| 日韩一二在线观看| 久久这里只有精品9| 一区二区成人在线观看| 日本美女xxx| hitomi一区二区三区精品| youjizzxxxx18| 黄色亚洲大片免费在线观看| 亚洲欧洲三级| 日韩mv欧美mv国产网站| 91视频国产一区| 成人性生活视频| 欧美俄罗斯性视频| 免费在线观看黄色| 亚洲新声在线观看| 偷拍精品一区二区三区| 91精品婷婷国产综合久久性色| 9i看片成人免费看片| 一区二区三区精品久久久| 自拍偷拍你懂的| 91免费国产在线| 九色91porny| 久久99精品视频| 日韩中文字幕二区| 亚洲少妇诱惑| 999久久欧美人妻一区二区| 三级电影一区| 日韩精品一区二区三区外面 | 亚洲人a成www在线影院| 刘亦菲久久免费一区二区| 欧美日本乱大交xxxxx| 无码人妻熟妇av又粗又大| 午夜精品福利视频网站| 欧美精品99久久久| 中文字幕制服丝袜一区二区三区| 日本一级免费视频| 91色乱码一区二区三区| 欧美性生交xxxxx| 国产成人亚洲精品青草天美 | 欧美久久一区二区三区| 国产又爽又黄的激情精品视频| 成人午夜精品| 国产精品成熟老女人| 欧美电影免费观看| 日韩美女av在线免费观看| 国产网站在线| 97成人在线视频| 亚洲私拍视频| 欧美一区二三区| 日韩伦理精品| 欧美最近摘花xxxx摘花| 韩国久久久久久| 国产成人精品av在线| 玛雅亚洲电影| 国产精品9999| 亚洲青青久久| 99re在线播放| 美女视频免费精品| 久久精品日产第一区二区三区| 欧洲精品一区| 日本高清久久一区二区三区| 黑人操亚洲人| 伊人久久大香线蕉午夜av| 先锋资源久久| 国产欧美久久久久| 最新亚洲一区| 日韩一级免费在线观看| 日本欧美一区二区三区乱码| 黑森林精品导航| 黄页视频在线91| 亚洲av午夜精品一区二区三区| 成人丝袜视频网| 免费黄色在线视频| 亚洲国产成人自拍| 亚洲精品久久久久久国| 一区二区三区不卡视频在线观看| 麻豆91精品91久久久| 亚洲国产成人91porn| 亚洲黄色免费观看| 欧美亚洲国产bt| 精品国产va久久久久久久| 亚洲经典中文字幕| 国产在线你懂得| 久久网福利资源网站| 超碰资源在线| 国产精品美腿一区在线看| 亚洲一区导航| 国产在线精品二区| 久久在线电影| 少妇人妻无码专区视频| 日韩av一区二区在线影视| 激情图片中文字幕| 91丝袜高跟美女视频| 欧美xxxooo| 欧美日韩国产影院| 夜夜骚av一区二区三区| 亚洲第一av网| 精精国产xxxx视频在线| 欧美亚洲成人网| 99久久久国产| 日韩av图片| 亚洲片区在线| 加勒比av中文字幕| 26uuu久久综合| 激情视频在线播放| 欧美性猛交xxxx免费看| 国产黄色高清视频| 国产亚洲精品一区二区| 超碰中文在线| 亚洲一区免费网站| 精品欧美久久| ww国产内射精品后入国产| 精品一区二区三区视频在线观看 | 亚洲综合激情网| 伊人网综合在线| 日韩av在线播放资源| 91麻豆免费在线视频| 国产精品午夜视频| 曰本一区二区三区视频| av在线com| 国产伦精品一区二区三区免费| av网站免费在线看| 无吗不卡中文字幕| 丰满熟妇乱又伦| 久久久国产精品视频| 日韩欧美少妇| 欧美精品久久久| 中日韩男男gay无套| 蜜臀aⅴ国产精品久久久国产老师| 国产精品久久久久影视| 无码人妻精品一区二区| 日韩精品电影网| √8天堂资源地址中文在线| 91探花福利精品国产自产在线| 第一sis亚洲原创| 色国产在线视频| 久久久国产综合精品女国产盗摄| 国产一级淫片a| 欧美精品一区视频| 色网在线观看| 国产aⅴ精品一区二区三区黄| 我不卡影院28| www.久久av.com| 亚洲视频每日更新| 中文字幕永久免费视频| 中文日韩电影网站| 国产精品一区二区免费福利视频 | 香蕉视频在线看| 国产一区视频在线播放| 国产大片一区| 亚洲AV无码久久精品国产一区| 亚洲日本乱码在线观看| 999精品国产| 欧美激情精品久久久久久免费印度 | 影音先锋一区| 国产精品扒开腿做爽爽爽a片唱戏| 亚洲一区二区在线播放相泽| 亚洲老妇色熟女老太| 久久青草福利网站| 日韩手机在线| 国产一级不卡毛片| 国产精品久久久久久久久免费樱桃 | 午夜亚洲一区| 欧美成人国产精品一区二区| 欧美性生交片4| 国产区在线看| 国产精品免费在线| 国产精品夜夜夜| 性少妇xx生活| 日韩欧美高清dvd碟片| 第一福利在线视频| 欧美一区二区视频17c| 麻豆一区二区在线| 真实国产乱子伦对白在线| 欧美精品一区二区三区蜜桃| 高清不卡亚洲| 一区精品视频| 成人动漫精品一区二区| 在线观看 亚洲| 美女国内精品自产拍在线播放| 黄色免费大全亚洲| av免费网站观看| 亚洲男人天堂av| 日韩二区三区| 成人黄色大片在线免费观看| 在线成人h网| 一级黄色片网址| 日韩亚洲电影在线| 亚洲黄色免费看| 欧美少妇在线观看| 久久麻豆一区二区| 国产欧美日韩成人| 57pao国产成人免费| 亚洲91中文字幕无线码三区| 一级黄色片毛片| 欧美日韩色综合| a国产在线视频| 亚洲欧洲国产精品久久| 成人中文字幕电影| 日批视频免费观看| 久久久久久久久久久免费| 国内成人精品| 久久国产劲爆∧v内射| 欧美日韩在线不卡| 国产精选在线| 国产制服91一区二区三区制服| 国产亚洲精品7777| 韩国av永久免费|