亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

《Java并發編程實戰》- 個人閱讀總結(一)

2019-11-06 06:25:40
字體:
來源:轉載
供稿:網友

背景

前段時間想更深入了解下java多線程相關的知識,對Java多線程有一個全面的認識,所以想找一本Java多線程相關的書籍來閱讀,最后我選擇了《Java并發編程實戰》這本個人認為還算相當不錯,至于為什么選擇它,下面有介紹。

書的介紹

中文書名:《Java并發編程實戰》 英文書名:《Java Concurrency in PRactice》 作者:Brian Goetz / Tim Peierls / Joshua Bloch / Joseph Bowbeer / David Holmes / Doug Lea 譯者:童云蘭 出版社: 機械工業出版社華章公司 購買可以在各大電商網站搜索書名購買,請支持正版 圖書封面

選擇該書原因

1、亞馬遜排名考前,評論多評分也不錯; 2、很多java程序員必看數據整理里面的書單之一; 3、豆瓣評分9.0; 4、作者都很牛B。

圖書簡介

《Java并發編程實戰》深入淺出地介紹了Java線程和并發,是一本完美的Java并發參考手冊。書中從并發性和線程安全性的基本概念出發,介紹了如何使用類庫提供的基本并發構建塊,用于避免并發危險、 構造線程安全的類及驗證線程安全的規則,如何將小的線程安全類組合成更大的線程安全類,如何利用線程來提高并發應用程序的吞吐量,如何識別可并行執行的任務,如何提高單線程子系統的響應性,如 何確保并發程序執行預期任務,如何提高并發代碼的性能和可伸縮性等內容,最后介紹了一些高級主題,如顯式鎖、原子變量、非阻塞算法以及如何開發自定義的同步工具類。 《Java并發編程實戰》適合Java程序開發人員閱讀。

作者簡介

本書作者都是Java Community Process JSR 166專家組(并發工具)的主要成員,并在其他很多JCP專家組里任職。Brian Goetz有20多年的軟件咨詢行業經驗,并著有至少75篇關于Java開發的文章。 Tim Peierls是“現代多處理器”的典范,他在BoxPop.biz、唱片藝術和戲劇表演方面也頗有研究。Joseph Bowbeer是一個Java ME專家,他對并發編程的興趣始于Apollo計算機時代。David Holmes是 《The Java Programming Language》一書的合著者,任職于Sun公司。Joshua Bloch是Google公司的首席Java架構師,《Effective Java》一書的作者,并參與著作了《Java Puzzlers》。Doug Lea 是《Concurrent Programming》一書的作者,紐約州立大學 Oswego分校的計算機科學教授。 備注:縮寫的解釋如下 - Java Community Process(JCP) wiki 英文介紹 wiki 中文介紹 - Java Specification Requests(JSR)

一些需要提前掌握的基礎

進程與線程

進程與線程的解釋

線程 & 進程 & 服務器硬件之間的關系

總核數 = 物理CPU個數 X 每顆物理CPU的核數 總邏輯CPU數 = 物理CPU個數 X 每顆物理CPU的核數 X 超線程數 同一進程中的多條線程將共享該進程中的全部系統資源,如虛擬地址空間,文件描述符和信號處理等等。 但同一進程中的多個線程有各自的調用棧(call stack),自己的寄存器環境(register context),自己的線程本地存儲(thread-local storage)。 大量用戶線程復用少量的輕權進程(內核線程)進程才是程序(那些指令和數據)的真正運行實例。若干進程有可能與同一個程序相關系,且每個進程皆可以同步(循序)或異步(平行)的方式獨立運行。

進程之間切換的原理以及代價

進程狀態轉換圖 進程狀態的轉換參考下面兩篇博文 進程的狀態轉換 linux進程狀態解析

操作系統基本原理

了解操作系統的基本原理對多線程的理解也是至關重要的,下面的這篇博文對操作系統的闡述比較形象易懂。 操作系統基本原理 總結如下: - 以多進程形式,允許多個任務同時運行 - 以多線程形式,允許單個任務分成不同的部分運行 - 提供協調機制,一方面防止進程之間和線程之間產生沖突,另一方面允許進程之間和線程之間共享資源

簡介

并發簡史

早期的計算機中不包含操作系統,它們從頭到尾執行一個程序,程序可訪問計算機上面的所有資源。這樣會造成極大的資源浪費。 操作系統的出現使得計算機可以每次運行多個程序,操作系統為每個進程分配資源。 之所以在計算機中加入操作系統來實現多個程序通知執行,主要基于下面三個原因。 - 資源利用率 - 公平性 - 便利性

線程優勢

那么引入多線程會有哪些優勢呢? - 發揮多處理器的強大能力 - 使建模更具簡單性 - 異步事件的簡化處理 不同類型的任務、負責自己的工作流。log4j的日志異步輸出,消息監控功能、這樣的線程可以專注自己的任務。

線程帶來的風險

線程也帶來了一些風險 - 安全性問題 - 活躍性問題 - 性能問題

基礎知識

線程安全性

什么是線程安全性?該書給出了自己的定義:當多個線程訪問某個類時,這個類始終都能表現正確的行為。

原子性加鎖機制用鎖保護狀態 java中與線程安全相關的關鍵詞:synchronized、Explicit Lock。synchronized 與 Explict Lock 大部分時候可以相互替代。

對象的共享

可見性線程封閉不變性安全發布

java中與對象共享相關的關鍵詞:Volatile、ThreadLocal、Final Volatile 變量具有 synchronized 的可見性特性,但是不具備原子特性。線程為了提高效率,將某成員變量(如A)拷貝了一份(如B),線程中對A的訪問其實訪問的是B。只在某些動作時才進行A和B的同步。因此存在A和B不一致的情況。volatile就是用來避免這種情況的。volatile告訴jvm, 它所修飾的變量不保留拷貝,直接訪問主內存中的(也就是上面說的A)

安全發布的常用模式

在靜態初始化函數中初始化對象將對象的引用保存到volatile類型的域或AtomicReferance中將對象的應用保存到某個正確的構造對象的final域中將對象的引用保存到一個由鎖保護的域中

對象組合

設計線程安全的類實例封閉線程安全性的委托在現有的線程安全類中添加功能將同步策略文檔化 在設計線程安全類的過程中,需要包含以下三個基本要素: 找出構成對象狀態的所有變量。 找出約束狀態變量的不變性條件。 建立對象狀態的并發訪問管理策略。

舉例

實例封閉–PersonSet@ThreadSafepublic class PersonSet { @GuardedBy("this") private final Set<Person> mySet = new HashSet<Person>(); public synchronized void addPerson(Person p) { mySet.add(p); } public synchronized boolean containsPerson(Person p) { return mySet.contains(p); } interface Person { }}線程安全性的委托-DelegatingVehicleTracker(委托成功)NumberRange(委托失?。?** * DelegatingVehicleTracker * <p/> * Delegating thread safety to a ConcurrentHashMap * * @author Brian Goetz and Tim Peierls */@ThreadSafepublic class DelegatingVehicleTracker { private final ConcurrentMap<String, Point> locations; private final Map<String, Point> unmodifiableMap; public DelegatingVehicleTracker(Map<String, Point> points) { locations = new ConcurrentHashMap<String, Point>(points); unmodifiableMap = Collections.unmodifiableMap(locations); } public Map<String, Point> getLocations() { return unmodifiableMap; } public Point getLocation(String id) { return locations.get(id); } public void setLocation(String id, int x, int y) { if (locations.replace(id, new Point(x, y)) == null) throw new IllegalArgumentException("invalid vehicle name: " + id); } // Alternate version of getLocations (Listing 4.8) public Map<String, Point> getLocationsAsStatic() { return Collections.unmodifiableMap( new HashMap<String, Point>(locations)); }}

監視器模式

監視器是操作系統實現同步的重要基礎概念,同樣它也用在JAVA的線程同步中監視器可以看做是經過特殊布置的建筑,這個建筑有一個特殊的房間,該房間通常包含一些數據和代碼,但是一次只能一個消費者(thread)使用此房間,當一個消費者(線程)使用了這個房間,首先他必須到一個大廳(Entry Set)等待,調度程序將基于某些標準(e.g. FIFO)將從大廳中選擇一個消費者(線程),進入特殊房間,如果這個線程因為某些原因被“掛起”,它將被調度程序安排到“等待房間”,并且一段時間之后會被重新分配到特殊房間,按照上面的線路,這個建筑物包含三個房間,分別是“特殊房間”、“大廳”以及“等待房間”。 簡單來說,監視器用來監視線程進入這個特別房間,他確保同一時間只能有一個線程可以訪問特殊房間中的數據和代碼。(synchronized) 這里寫圖片描述 這里寫圖片描述

基礎構建模塊

同步容器類并發容器阻塞隊列和生產-消費者模式阻塞方法與中斷方法同步工具

構建高效可用的緩存

java中早期的同步容器有: Collections.synchronizedXxx (早期jdk)、Vector、Hashtable java5.0版本之后開始出現效率更高的并發容器: java.util.concurrent(Java5.0)、ConcurrentHashMap、CopyOnWriteArrayList、 BlockingQueue

同步/并發容器對比

這里寫圖片描述 從圖可以看出HashTable 和 ConcurrentHashMap兩者最大的差異在鎖的粒度,HashTable 的鎖是對整個散列表的全局鎖,而ConcurrentHashMap的鎖粒度更細。 ConcurrentHashMap 鎖的粒度是–Segment(桶)。 查看ConcurrentHashMap 的源碼,get() 和 put()方法。

public V get(Object key) { Segment<K,V> s; // manually integrate access methods to reduce overhead HashEntry<K,V>[] tab; int h = hash(key); long u = (((h >>> segmentShift) & segmentMask) << SSHIFT) + SBASE; if ((s = (Segment<K,V>)UNSAFE.getObjectVolatile(segments, u)) != null && (tab = s.table) != null) { for (HashEntry<K,V> e = (HashEntry<K,V>) UNSAFE.getObjectVolatile (tab, ((long)(((tab.length - 1) & h)) << TSHIFT) + TBASE); e != null; e = e.next) { K k; if ((k = e.key) == key || (e.hash == h && key.equals(k))) return e.value; } } return null; }final V put(K key, int hash, V value, boolean onlyIfAbsent) { HashEntry<K,V> node = tryLock() ? null : scanAndLockForPut(key, hash, value); V oldValue; try { HashEntry<K,V>[] tab = table; int index = (tab.length - 1) & hash; HashEntry<K,V> first = entryAt(tab, index); for (HashEntry<K,V> e = first;;) { if (e != null) { K k; if ((k = e.key) == key || (e.hash == hash && key.equals(k))) { oldValue = e.value; if (!onlyIfAbsent) { e.value = value; ++modCount; } break; } e = e.next; } else { if (node != null) node.setNext(first); else node = new HashEntry<K,V>(hash, key, value, first); int c = count + 1; if (c > threshold && tab.length < MAXIMUM_CAPACITY) rehash(node); else setEntryAt(tab, index, node); ++modCount; count = c; oldValue = null; break; } } } finally { unlock(); } return oldValue; }

其中兩個內置類需要特別注意下,這兩個是構建分段加鎖和性能提升的關鍵點。 HashEntry: 可以看到除了value不是final的,其它值都是final的,這意味著不能從hash鏈的中間或尾部添加或刪除節點,因為這需要修改next 引用值,所有的節點的修改只能從頭部開始。對于put操作,可以一律添加到Hash鏈的頭部。但是對于remove操作,可能需要從中間刪除一個節點,這就需要將要刪除節點的前面所有節點整個復制一遍,最后一個節點指向要刪除結點的下一個結點。這在講解刪除操作時還會詳述。為了確保讀操作能夠看到最新的值,將value設置成volatile,這避免了加鎖。 Segment Hash表的一個很重要方面就是如何解決hash沖突,ConcurrentHashMap 和HashMap使用相同的方式,都是將hash值相同的節點放在一個hash鏈中。與HashMap不同的是,ConcurrentHashMap使用多個子Hash表,也就是段(Segment)。

java線程狀態轉換

線程的狀態圖 這個圖是不是很熟悉? Yield是一個靜態的原生(native)方法 Yield告訴當前正在執行的線程把運行機會交給線程池中擁有相同優先級的線程。 Yield不能保證使得當前正在運行的線程迅速轉換到可運行的狀態 它僅能使一個線程從運行狀態轉到可運行狀態,而不是等待或阻塞狀態 join()運行著的線程將阻塞直到這個線程實例完成了執行 關鍵詞:start、notify、yield、blocked、waiting、sleep、join

同步工具類

信號量(Semaphore)閉鎖(Latch)柵欄(Barrier) 工具類:CountDownLatch、FutureTask、Semaphore、CyclicBarrier

閉鎖的作用相當與一扇門:在閉鎖到達結束狀態之前,這扇門一直關閉,沒有任何線程能通過,當達到狀態是,這扇門會打開允許所有線程通過。 閉鎖舉例:TestHarness 、Preloader

public class TestHarness { public long timeTasks(int nThreads, final Runnable task) throws InterruptedException { final CountDownLatch startGate = new CountDownLatch(1); final CountDownLatch endGate = new CountDownLatch(nThreads); for (int i = 0; i < nThreads; i++) { Thread t = new Thread() { public void run() { try { startGate.await(); //等待 try { task.run(); } finally { endGate.countDown();//執行完成之后釋放 } } catch (InterruptedException ignored) { } } }; t.start(); } long start = System.nanoTime(); startGate.countDown(); //釋放線程 endGate.await();//等待釋放 long end = System.nanoTime(); return end - start; }}

柵欄和閉鎖和類似,閉鎖是等待事件,柵欄是等待其他線程 柵欄舉例:CellularAutomata

public class CellularAutomata { private final Board mainBoard; private final CyclicBarrier barrier; private final Worker[] workers; public CellularAutomata(Board board) { this.mainBoard = board; int count = Runtime.getRuntime().availableProcessors(); this.barrier = new CyclicBarrier(count, new Runnable() { public void run() { mainBoard.commitNewValues(); }}); this.workers = new Worker[count]; for (int i = 0; i < count; i++) workers[i] = new Worker(mainBoard.getSubBoard(count, i)); } private class Worker implements Runnable { private final Board board; public Worker(Board board) { this.board = board; } public void run() { while (!board.hasConverged()) { for (int x = 0; x < board.getMaxX(); x++) for (int y = 0; y < board.getMaxY(); y++) board.setNewValue(x, y, computeValue(x, y)); try { barrier.await(); } catch (InterruptedException ex) { return; } catch (BrokenBarrierException ex) { return; } } } private int computeValue(int x, int y) { // Compute the new value that goes in (x,y) return 0; } } public void start() { for (int i = 0; i < workers.length; i++) new Thread(workers[i]).start(); mainBoard.waitForConvergence(); } interface Board { int getMaxX(); int getMaxY(); int getValue(int x, int y); int setNewValue(int x, int y, int value); void commitNewValues(); boolean hasConverged(); void waitForConvergence(); Board getSubBoard(int numPartitions, int index); }}

構建高效可伸縮的緩存

個人覺得在項目中可以用到最多的就是FutureTask,下面舉例來說明試用FutureTask的好處。下面是一個緩存類的設計。

public class Memoizer1 <A, V> implements Computable<A, V> { @GuardedBy("this") private final Map<A, V> cache = new HashMap<A, V>(); private final Computable<A, V> c; public Memoizer1(Computable<A, V> c) { this.c = c; } /** * 帶來了性能問題,每次只有一個線程可以執行該方法 */ public synchronized V compute(A arg) throws InterruptedException { V result = cache.get(arg); if (result == null) { result = c.compute(arg); cache.put(arg, result); } return result; }}

這里寫圖片描述 上面Memoizer1的設計是非常糟糕,帶來了性能問題,每次只有一個線程可以執行該方法.如上圖所示,下面對這個對象進行改進。

public class Memoizer2 <A, V> implements Computable<A, V> { private final Map<A, V> cache = new ConcurrentHashMap<A, V>(); private final Computable<A, V> c; public Memoizer2(Computable<A, V> c) { this.c = c; } public V compute(A arg) throws InterruptedException { V result = cache.get(arg); if (result == null) { result = c.compute(arg); cache.put(arg, result); } return result; }}

這里寫圖片描述 大量請求同時調用時還是會有比較嚴重的性能問題,c.compute(arg)的計算結果時間較長時,只要結果還未計算出來,每個請求線程都會對結果重新計算一次,如上圖所示。下面引入TaskFutrue來實現。

public class Memoizer3 <A, V> implements Computable<A, V> { private final Map<A, Future<V>> cache = new ConcurrentHashMap<A, Future<V>>(); private final Computable<A, V> c; public Memoizer3(Computable<A, V> c) { this.c = c; } /** * 該方法大大減少了并發多次計算的過程,但是還是會有可以重復計算,在獲取 */ public V compute(final A arg) throws InterruptedException { Future<V> f = cache.get(arg); if (f == null) { Callable<V> eval = new Callable<V>() { public V call() throws InterruptedException { return c.compute(arg); } }; FutureTask<V> ft = new FutureTask<V>(eval); f = ft; cache.put(arg, ft); ft.run(); // call to c.compute happens here 這里調用 c.compute(arg) } try { return f.get(); } catch (ExecutionException e) { throw LaunderThrowable.launderThrowable(e.getCause()); } }}

這里寫圖片描述 該方法大大減少了并發多次計算的過程,但是還是會有可以重復計算,在獲取Future f = cache.get(arg)之后判斷if (f == null) 與put(arg, ft) 并不是原子性的操作,在這期間可能會計算多次,如上圖所示。 最終的解決方案引入了 ConcurrentMap.putIfAbsent(arg, ft)方法,只在不存在的時候才寫放入Future去計算。 最終的優化解決方案如下:

public class Memoizer <A, V> implements Computable<A, V> { private final ConcurrentMap<A, Future<V>> cache = new ConcurrentHashMap<A, Future<V>>(); private final Computable<A, V> c; public Memoizer(Computable<A, V> c) { this.c = c; } public V compute(final A arg) throws InterruptedException { while (true) { Future<V> f = cache.get(arg); if (f == null) { Callable<V> eval = new Callable<V>() { public V call() throws InterruptedException { return c.compute(arg); } }; FutureTask<V> ft = new FutureTask<V>(eval); f = cache.putIfAbsent(arg, ft); if (f == null) { f = ft; ft.run(); } } try { return f.get(); } catch (CancellationException e) { cache.remove(arg, f); } catch (ExecutionException e) { throw LaunderThrowable.launderThrowable(e.getCause()); } } }}

第一部分總結

個人覺得第一部分是非常重要的,看書的時候結合代碼和示例,去翻閱與之相關的知識融會貫通,舉一反三。通過這部分我們可以對java的多線程概念和相關的工具包有比較全面的了解,后面結合實際項目靈活運用好,遵循部分原則避免出現常見的異常和問題。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
97人人做人人爱| 久久人人爽人人爽人人片av高请| 亚洲免费视频观看| 欧美黑人狂野猛交老妇| 国产精品高潮呻吟久久av野狼| 日韩精品中文在线观看| 欧美大片免费观看在线观看网站推荐| 国产又爽又黄的激情精品视频| 全亚洲最色的网站在线观看| 国产精品日韩欧美| 精品国产鲁一鲁一区二区张丽| 日韩欧美国产视频| 免费91在线视频| 原创国产精品91| 亚洲a区在线视频| 亚洲精品成人久久久| 日韩在线高清视频| 国产日韩欧美成人| 国产主播在线一区| 亚洲天天在线日亚洲洲精| 日韩免费在线播放| 两个人的视频www国产精品| 国产精品一区二区久久国产| 亚洲变态欧美另类捆绑| 亚洲午夜精品久久久久久性色| 国产成人精品av| 亚洲免费视频网站| 欧美一级淫片播放口| 成人免费高清完整版在线观看| 色妞一区二区三区| 国产综合在线观看视频| 午夜精品久久17c| 91成人天堂久久成人| 精品久久久久久久久久国产| 亚洲欧美国产日韩天堂区| 97精品一区二区视频在线观看| 91丝袜美腿美女视频网站| 国产欧美日韩专区发布| 性日韩欧美在线视频| 91精品久久久久久| 成人中文字幕在线观看| 欧美午夜影院在线视频| 欧美国产日韩精品| 国产女人18毛片水18精品| 国产精品影院在线观看| 亚洲美女性生活视频| 欧美亚洲国产视频小说| 欧美超级免费视 在线| 欧美激情精品久久久久久久变态| 亚洲欧美日韩直播| 欧美另类老女人| 17婷婷久久www| 国产脚交av在线一区二区| 久久人人爽亚洲精品天堂| 国产午夜精品美女视频明星a级| 欧美性猛交xxxx乱大交极品| 成人久久一区二区| 欧美日本精品在线| 一本大道久久加勒比香蕉| 欧美香蕉大胸在线视频观看| 在线视频中文亚洲| 91手机视频在线观看| 不卡在线观看电视剧完整版| 日韩大陆欧美高清视频区| 久久精品国产免费观看| 波霸ol色综合久久| 欧美在线亚洲在线| 91视频九色网站| 成人乱人伦精品视频在线观看| 久久777国产线看观看精品| 国产在线观看不卡| 高清欧美性猛交xxxx| 成人在线精品视频| 国产91免费观看| 国产精品一二区| 操人视频在线观看欧美| 久久国产精品视频| 91免费国产网站| 日韩美女主播视频| 亚洲欧美激情四射在线日| 国产美女主播一区| 亚洲综合最新在线| 亚洲国产精品美女| 欧美精品日韩www.p站| 精品视频久久久久久| 福利一区福利二区微拍刺激| 91视频-88av| 日韩欧亚中文在线| 黄色成人在线播放| 亚洲色图17p| 亚洲精品国产精品久久清纯直播| 成人一区二区电影| 欧美久久精品一级黑人c片| 欧美电影院免费观看| 精品视频中文字幕| 国产男女猛烈无遮挡91| 国产亚洲综合久久| 国产精品高清在线| 精品小视频在线| 欧美高跟鞋交xxxxxhd| 国产一区二区久久精品| 最近2019好看的中文字幕免费| 欧美激情小视频| 91久久久国产精品| 成人亚洲欧美一区二区三区| 欧美黑人巨大xxx极品| 久久99热这里只有精品国产| 黄色精品一区二区| 成人美女免费网站视频| 色综合91久久精品中文字幕| 亚洲人成网站色ww在线| 懂色av一区二区三区| 中文字幕亚洲一区二区三区| 狠狠色狠狠色综合日日小说| 亚洲免费伊人电影在线观看av| 欧美亚洲激情视频| 日韩精品极品在线观看播放免费视频| 国产成人精品久久久| 国产中文字幕亚洲| 亚洲人成电影在线播放| 成人激情视频免费在线| 性欧美xxxx视频在线观看| 538国产精品视频一区二区| 久久精品国产2020观看福利| 欧美午夜久久久| 亚洲色图激情小说| 欧美激情精品久久久久久久变态| 日韩免费在线免费观看| 国产乱肥老妇国产一区二| 色偷偷噜噜噜亚洲男人| 亚洲精品99久久久久中文字幕| 日韩美女在线观看一区| 亚洲福利视频二区| 久久这里只有精品视频首页| 九九视频这里只有精品| 国产视频精品久久久| 成人黄色av免费在线观看| 97视频在线观看亚洲| 欧美大片在线看| 91九色视频导航| 狠狠色狠狠色综合日日小说| 午夜精品久久久久久久久久久久| 亚洲精品国产拍免费91在线| 国产精品视频网站| 亚洲三级免费看| 国产一区二区三区18| 91香蕉嫩草神马影院在线观看| 精品久久久久久久久久久久| 成人做爰www免费看视频网站| 亚洲女在线观看| 日韩成人高清在线| 久热99视频在线观看| 日韩av在线一区二区| 亚洲欧美国产日韩天堂区| 国产欧美精品日韩精品| 97激碰免费视频| 91高清视频免费观看| 欧美成年人在线观看| 欧美激情影音先锋| 欧美一区在线直播| 亚洲色图综合久久| 国产精品视频久久久久| 国产99视频在线观看| 成人黄色av播放免费|