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

Java關于延遲加載的一些應用實踐

開發 后端
在Java8中引入的lambda對于我們實現延遲操作提供很大的便捷性,如Stream、Supplier等,下面介紹幾個例子。

[[381098]]

 代碼中的很多操作都是Eager的,比如在發生方法調用的時候,參數會立即被求值。總體而言,使用Eager方式讓編碼本身更加簡單,然而使用Lazy的方式通常而言,即意味著更好的效率。

延遲初始化

一般有幾種延遲初始化的場景:

  •  對于會消耗較多資源的對象:這不僅能夠節省一些資源,同時也能夠加快對象的創建速度,從而從整體上提升性能。
  •  某些數據在啟動時無法獲取:比如一些上下文信息可能在其他攔截器或處理中才能被設置,導致當前bean在加載的時候可能獲取不到對應的變量的值,使用 延遲初始化可以在真正調用的時候去獲取,通過延遲來保證數據的有效性。

在Java8中引入的lambda對于我們實現延遲操作提供很大的便捷性,如Stream、Supplier等,下面介紹幾個例子。

Lambda

Supplier

通過調用get()方法來實現具體對象的計算和生成并返回,而不是在定義Supplier的時候計算,從而達到了_延遲初始化_的目的。但是在使用 中往往需要考慮并發的問題,即防止多次被實例化,就像Spring的@Lazy注解一樣。 

  1. public class Holder {  
  2.     // 默認第一次調用heavy.get()時觸發的同步方法  
  3.     private Supplier<Heavy> heavy = () -> createAndCacheHeavy();   
  4.     public Holder() {  
  5.         System.out.println("Holder created");  
  6.     }  
  7.     public Heavy getHeavy() {  
  8.         // 第一次調用后heavy已經指向了新的instance,所以后續不再執行synchronized  
  9.         return heavy.get();   
  10.     } 
  11.     //...  
  12.     private synchronized Heavy createAndCacheHeavy() {  
  13.         // 方法內定義class,注意和類內的嵌套class在加載時的區別  
  14.         class HeavyFactory implements Supplier<Heavy> {  
  15.             // 饑渴初始化  
  16.             private final Heavy heavyInstance = new Heavy();   
  17.             public Heavy get() {  
  18.                 // 每次返回固定的值 
  19.                 return heavyInstance;   
  20.             }   
  21.         }       
  22.         //第一次調用方法來會將heavy重定向到新的Supplier實例  
  23.         if(!HeavyFactory.class.isInstance(heavy)) {  
  24.             heavy = new HeavyFactory();  
  25.         }  
  26.         return heavy.get();  
  27.     }  

當Holder的實例被創建時,其中的Heavy實例還沒有被創建。下面我們假設有三個線程會調用getHeavy方法,其中前兩個線程會同時調用,而第三個線程會在稍晚的時候調用。

當前兩個線程調用該方法的時候,都會調用到createAndCacheHeavy方法,由于這個方法是同步的。因此第一個線程進入方法體,第二個線程開始等待。在方法體中會首先判斷當前的heavy是否是HeavyInstance的一個實例。

如果不是,就會將heavy對象替換成HeavyFactory類型的實例。顯然,第一個線程執行判斷的時候,heavy對象還只是一個Supplier的實例,所以heavy會被替換成為HeavyFactory的實例,此時heavy實例會被真正的實例化。

等到第二個線程進入執行該方法時,heavy已經是HeavyFactory的一個實例了,所以會立即返回(即heavyInstance)。當第三個線程執行getHeavy方法時,由于此時的heavy對象已經是HeavyFactory的實例了,因此它會直接返回需要的實例(即heavyInstance),和同步方法createAndCacheHeavy沒有任何關系了。

以上代碼實際上實現了一個輕量級的虛擬代理模式(Virtual Proxy Pattern)。保證了懶加載在各種環境下的正確性。

還有一種基于delegate的實現方式更好理解一些:

https://gist.github.com/taichi/6daf50919ff276aae74f 

  1. import java.util.concurrent.ConcurrentHashMap;  
  2. import java.util.concurrent.ConcurrentMap;  
  3. import java.util.function.Supplier;  
  4. public class MemoizeSupplier<T> implements Supplier<T> {  
  5.  final Supplier<T> delegate;  
  6.  ConcurrentMap<Class<?>, T> map = new ConcurrentHashMap<>(1);  
  7.  public MemoizeSupplier(Supplier<T> delegate) {  
  8.   this.delegate = delegate;  
  9.  }  
  10.  @Override  
  11.  public T get() {  
  12.      // 利用computeIfAbsent方法的特性,保證只會在key不存在的時候調用一次實例化方法,進而實現單例  
  13.   return this.map.computeIfAbsent(MemoizeSupplier.class,  
  14.     k -> this.delegate.get());  
  15.  }  
  16.  public static <T> Supplier<T> of(Supplier<T> provider) {  
  17.   return new MemoizeSupplier<>(provider);  
  18.  }  

以及一個更復雜但功能更多的CloseableSupplier: 

  1. public static class CloseableSupplier<T> implements Supplier<T>, Serializable {  
  2.         private static final long serialVersionUID = 0L 
  3.         private final Supplier<T> delegate;  
  4.         private final boolean resetAfterClose; 
  5.         private volatile transient boolean initialized;  
  6.         private transient T value;  
  7.         private CloseableSupplier(Supplier<T> delegate, boolean resetAfterClose) {  
  8.             this.delegate = delegate;  
  9.             this.resetAfterClose = resetAfterClose;  
  10.         }  
  11.         public T get() {  
  12.             // 經典Singleton實現  
  13.             if (!(this.initialized)) { // 注意是volatile修飾的,保證happens-before,t一定實例化完全  
  14.                 synchronized (this) {  
  15.                     if (!(this.initialized)) { // Double Lock Check  
  16.                         T t = this.delegate.get();  
  17.                         tthis.value = t;  
  18.                         this.initialized = true 
  19.                         return t;  
  20.                     }  
  21.                 }  
  22.             }  
  23.             // 初始化后就直接讀取值,不再同步搶鎖  
  24.             return this.value;  
  25.         } 
  26.         public boolean isInitialized() {  
  27.             return initialized;  
  28.         }  
  29.         public <X extends Throwable> void ifPresent(ThrowableConsumer<T, X> consumer) throws X {  
  30.             synchronized (this) {  
  31.                 if (initialized && this.value != null) {  
  32.                     consumer.accept(this.value);  
  33.                 }  
  34.             }  
  35.         } 
  36.         public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {  
  37.             checkNotNull(mapper);  
  38.             synchronized (this) {  
  39.                 if (initialized && this.value != null) {  
  40.                     return ofNullable(mapper.apply(value));  
  41.                 } else {  
  42.                     return empty();  
  43.                 }  
  44.             }  
  45.         }  
  46.         public void tryClose() {  
  47.             tryClose(i -> { });  
  48.         }  
  49.         public <X extends Throwable> void tryClose(ThrowableConsumer<T, X> close) throws X {  
  50.             synchronized (this) {  
  51.                 if (initialized) {  
  52.                     close.accept(value);  
  53.                     if (resetAfterClose) {  
  54.                         this.value = null 
  55.                         initialized = false 
  56.                     }  
  57.                 }  
  58.             }  
  59.         }  
  60.         public String toString() {  
  61.             if (initialized) {  
  62.                 return "MoreSuppliers.lazy(" + get() + ")";  
  63.             } else {  
  64.                 return "MoreSuppliers.lazy(" + this.delegate + ")";  
  65.             }  
  66.         }  
  67.     } 

Stream

Stream中的各種方法分為兩類:

  •  中間方法(limit()/iterate()/filter()/map())
  •  結束方法(collect()/findFirst()/findAny()/count())

前者的調用并不會立即執行,只有結束方法被調用后才會依次從前往后觸發整個調用鏈條。但是需要注意,對于集合來說,是每一個元素依次按照處理鏈條執行到尾,而不是每一個中間方法都將所有能處理的元素全部處理一遍才觸發 下一個中間方法。比如: 

  1. List<String> names = Arrays.asList("Brad", "Kate", "Kim", "Jack", "Joe", "Mike");  
  2. final String firstNameWith3Letters = names.stream()  
  3.     .filter(name -> length(name) == 3)  
  4.     .map(name -> toUpper(name))  
  5.     .findFirst()  
  6.     .get();  
  7. System.out.println(firstNameWith3Letters); 

當觸發findFirst()這一結束方法的時候才會觸發整個Stream鏈條,每個元素依次經過filter()->map()->findFirst()后返回。所以filter()先處理第一個和第二個后不符合條件,繼續處理第三個符合條件,再觸發map()方法,最后將轉換的結果返回給findFirst()。所以filter()觸發了_3_次,map()觸發了_1_次。

好,讓我們來看一個實際問題,關于無限集合。

Stream類型的一個特點是:它們可以是無限的。這一點和集合類型不一樣,在Java中的集合類型必須是有限的。Stream之所以可以是無限的也是源于Stream「懶」的這一特點。

Stream只會返回你需要的元素,而不會一次性地將整個無限集合返回給你。

Stream接口中有一個靜態方法iterate(),這個方法能夠為你創建一個無限的Stream對象。它需要接受兩個參數:

public static Stream iterate(final T seed, final UnaryOperator f)

其中,seed表示的是這個無限序列的起點,而UnaryOperator則表示的是如何根據前一個元素來得到下一個元素,比如序列中的第二個元素可以這樣決定:f.apply(seed)。

下面是一個計算從某個數字開始并依次返回后面count個素數的例子: 

  1. public class Primes {      
  2.     public static boolean isPrime(final int number) {  
  3.         return number > 1 &&  
  4.             // 依次從2到number的平方根判斷number是否可以整除該值,即divisor  
  5.             IntStream.rangeClosed(2, (int) Math.sqrt(number))  
  6.                 .noneMatch(divisor -> number % divisor == 0);  
  7.     }   
  8.     private static int primeAfter(final int number) {  
  9.         if(isPrime(number + 1)) // 如果當前的數的下一個數是素數,則直接返回該值  
  10.             return number + 1;  
  11.         else // 否則繼續從下一個數據的后面繼續找到第一個素數返回,遞歸  
  12.             return primeAfter(number + 1);  
  13.     }  
  14.     public static List<Integer> primes(final int fromNumber, final int count) {  
  15.         return Stream.iterate(primeAfter(fromNumber - 1), Primes::primeAfter)  
  16.             .limit(count)  
  17.             .collect(Collectors.<Integer>toList());  
  18.     }  
  19.     //...  

對于iterate和limit,它們只是中間操作,得到的對象仍然是Stream類型。對于collect方法,它是一個結束操作,會觸發中間操作來得到需要的結果。

如果用非Stream的方式需要面臨兩個問題:

  •  一是無法提前知曉fromNumber后count個素數的數值邊界是什么
  •  二是無法使用有限的集合來表示計算范圍,無法計算超大的數值

即不知道第一個素數的位置在哪兒,需要提前計算出來第一個素數,然后用while來處理count次查找后續的素數。可能primes方法的實現會拆成兩部分,實現復雜。如果用Stream來實現,流式的處理,無限迭代,指定截止條件,內部的一套機制可以保證實現和執行都很優雅。 

 

責任編輯:龐桂玉 來源: Java知音
相關推薦

2017-05-02 21:08:35

開發架構工程師

2024-12-27 10:51:53

2018-06-29 14:51:41

Java健壯性實踐

2009-06-18 09:51:25

Java繼承

2022-04-02 14:43:59

Promethues監控

2012-09-25 10:03:56

JavaJava封面Java開發

2011-07-13 09:13:56

Android設計

2021-10-21 06:52:17

Vue3組件 API

2011-03-11 09:27:11

Java性能監控

2013-04-07 10:40:55

前端框架前端

2011-03-15 17:46:43

2017-09-05 09:17:47

Java編程用法總結

2012-04-19 10:06:55

微軟Windows 8 E

2015-12-04 10:04:53

2022-04-14 10:22:44

故事卡業務

2020-09-28 06:45:42

故障復盤修復

2009-06-04 16:28:43

EJB常見問題

2017-12-21 07:54:07

2010-11-02 14:11:15

SilverlightWPF微軟開發

2022-05-19 07:52:39

MLOps云計算實機器學習
點贊
收藏

51CTO技術棧公眾號

国产午夜精品久久久| 欧美视频在线免费| 亚洲综合在线中文字幕| 亚洲欧美在线视频免费| 国产精品三级| 欧美一区二区三区四区高清 | 色综合狠狠操| 欧美精品一区二区精品网| 狠狠爱免费视频| 二区三区四区高清视频在线观看| 99久久99久久精品免费看蜜桃| 国产精品久久久久久中文字| 国产亚洲色婷婷久久99精品| 精品日韩免费| 精品国产免费一区二区三区香蕉| 999精品网站| 丁香花高清在线观看完整版| 国产精品久久久久久福利一牛影视| av一区二区在线看| 伊人网免费视频| 性久久久久久| 欧美激情区在线播放| 亚洲直播在线一区| 一区二区亚洲欧洲国产日韩| 日韩 欧美 高清| 在线观看a级片| 国产目拍亚洲精品99久久精品 | 6080亚洲理论片在线观看| 91福利国产成人精品照片| 人妻av无码专区| 欧美被日视频| 中文字幕欧美国产| 久久久人人爽| 五月天福利视频| 国产成人免费在线观看不卡| 国产精品专区一| 天天干天天色综合| 亚洲伊人网站| 久久久在线视频| 久久精品www| 综合久久久久| 久热在线中文字幕色999舞| 韩国三级hd中文字幕| 精品在线手机视频| 亚洲免费影视第一页| 亚洲国产果冻传媒av在线观看| 一区二区三区在线免费看 | 韩国福利在线| 2017欧美狠狠色| 玖玖玖精品中文字幕| 人妻精品一区二区三区| 成人少妇影院yyyy| 国精产品一区二区| 香蕉视频网站在线| 久久精品亚洲精品国产欧美 | 天堂аⅴ在线地址8| 亚洲国产精品ⅴa在线观看| 日本午夜精品电影| www.亚洲免费| 中文字幕一区二区三| 杨幂一区欧美专区| 成视频免费观看在线看| 亚洲精品va在线观看| 大地资源网在线观看免费官网| xvideos国产在线视频| 亚洲美女偷拍久久| www.亚洲视频.com| 亚洲欧洲日本韩国| 欧美影院一区二区| 图片区乱熟图片区亚洲| 日韩影片在线观看| 日韩精品极品在线观看| 色哟哟精品观看| 欧美gay男男猛男无套| 久久成人在线视频| 日本三级黄色大片| 久久国产88| 国产又爽又黄的激情精品视频| 91久久久久国产一区二区| 国内精品视频一区二区三区八戒| 7777精品久久久大香线蕉小说| 欧美 日韩 国产 成人 在线 91| 91色乱码一区二区三区| 亚洲电影一二三区| 青青草原av在线| 欧美午夜xxx| 99日在线视频| 人人精品亚洲| 色噜噜亚洲精品中文字幕| 欧美三级在线免费观看| 久久精品盗摄| 97netav| 日韩av视屏| 亚洲视频狠狠干| 92看片淫黄大片一级| 99精品视频在线免费播放| 亚洲高清在线观看| 男人av资源站| 羞羞答答国产精品www一本| 国产一区香蕉久久| 日本福利在线观看| 亚洲美女屁股眼交3| 国产又大又硬又粗| 亚洲精品一区国产| 中文国产成人精品| 日韩免费在线视频观看| 久久av中文字幕片| 欧美理论一区二区| 成人性生交大片免费看在线播放| 在线观看日韩一区| 无码成人精品区在线观看| 欧美高清在线| 国产成人精品在线观看| 懂色av蜜臀av粉嫩av分享吧| 国产精品久久三| 欧美性久久久久| 91久久偷偷做嫩草影院电| 少妇高潮久久77777| 五月天婷婷久久| 成人综合婷婷国产精品久久蜜臀 | 日韩欧美一级在线播放| 五月婷婷欧美激情| 久久蜜桃精品| 九九九九精品九九九九| 美女网站视频在线| 日韩欧美你懂的| 五月天色婷婷丁香| 美日韩一区二区三区| 欧美日韩电影一区二区| 国产在线美女| 亚洲电影中文字幕| 免费在线观看亚洲| 国产凹凸在线观看一区二区| 一区二区三区四区五区视频| 免费高清视频在线一区| 亚洲视频一区二区三区| 青青国产在线观看| 99在线视频精品| 日韩人妻无码精品久久久不卡| 亚洲成人影音| 欧美激情18p| 性少妇videosexfreexxx片| 亚洲同性gay激情无套| 最新天堂在线视频| 三级电影一区| 91久热免费在线视频| 日本中文字幕在线视频| 欧美日韩精品免费| 国产一区第一页| 精品一区二区日韩| 一级全黄肉体裸体全过程| 伊人久久一区| 久久91精品国产| 亚洲不卡免费视频| 性做久久久久久免费观看欧美| 五月天丁香社区| 国内成人在线| 精品免费二区三区三区高中清不卡| av色在线观看| 亚洲精品自拍第一页| 中文字幕视频网| 国产日韩欧美麻豆| 日韩高清第一页| 91精品在线观看国产| 99精品国产高清在线观看| 女子免费在线观看视频www| 欧美精品一区二区三区高清aⅴ| 激情五月色婷婷| 久久婷婷色综合| 亚洲va在线va天堂va偷拍| 亚洲精品成人| 国产一区二区三区高清视频| 亚洲成av在线| 久久色免费在线视频| 亚洲女同志亚洲女同女播放| 天天综合色天天综合| 国产jjizz一区二区三区视频| 美女久久久精品| 国产一区 在线播放| 亚洲精品无吗| 国产专区精品视频| aa级大片免费在线观看| 国产一区二区三区在线观看视频| 97精品人妻一区二区三区| 亚洲国产美女搞黄色| 在线免费观看麻豆| 黑人巨大精品欧美一区| 大j8黑人w巨大888a片| 日韩精品91| 春色成人在线视频| 精品三区视频| 久久久久久国产免费| 95在线视频| 亚洲精品国产suv| 亚洲熟女乱色一区二区三区久久久| 亚洲一区二区影院| 在线观看免费黄色网址| 成人网男人的天堂| 在线观看免费视频高清游戏推荐| 亚洲成人原创| 一个色的综合| 深爱激情综合网| 国产经品一区二区| 91精品亚洲一区在线观看| 亚州av一区二区| 黄色网址在线免费观看| 亚洲欧洲在线免费| 丰满人妻熟女aⅴ一区| 欧美久久久久久蜜桃| 国产婷婷色一区二区在线观看| 亚洲欧美激情小说另类| 国产传媒国产传媒| 久久综合色婷婷| 亚洲视频天天射| 黑人巨大精品欧美黑白配亚洲| 免费国产成人av| 国产欧美日本| 中国丰满熟妇xxxx性| 久久久久久久久丰满| 天天综合狠狠精品| 小说区图片区色综合区| 国产精品视频500部| 99精品视频在线免费播放| 国产精品一久久香蕉国产线看观看| 国产社区精品视频| 欧美精品成人91久久久久久久| 黄色在线视频网站| 日韩在线观看免费全| 国内在线免费高清视频| 亚洲乱码国产乱码精品精| 少妇高潮一区二区三区69| 精品久久久久久久久久久久久久久| 一级做a爱片性色毛片| 欧美自拍偷拍一区| 久久影视中文字幕| 日韩欧美精品网站| 天天干天天色综合| 91黄视频在线观看| 天堂av免费在线观看| 色就色 综合激情| 日本黄色一级视频| 色老头久久综合| 久久久久久无码精品大片| 色婷婷综合久久久中文字幕| 久草手机在线观看| 欧美性xxxxxxx| 国产精品777777| 色婷婷综合中文久久一本| 无码人妻丰满熟妇精品区| 欧美在线观看一二区| 国产精品传媒在线观看| 欧美揉bbbbb揉bbbbb| 又污又黄的网站| 91精品综合久久久久久| 国产不卡精品视频| 亚洲成在人线av| 天天操天天操天天操| 日韩不卡在线观看| 国产免费av高清在线| 最新91在线视频| 成人看av片| 国内自拍欧美激情| 中文字幕乱码中文乱码51精品 | 亚洲精品无播放器在线播放| 亚洲a级在线观看| 999在线精品| 蜜桃麻豆www久久国产精品| 国产区精品区| 宅男一区二区三区| 午夜久久影院| 国产免费黄色小视频| 久久精品卡一| 深爱五月综合网| 91在线云播放| 在线日韩国产网站| 亚洲午夜视频在线观看| 精品久久久久久久久久久久久久久久| 欧美日韩亚洲综合在线 欧美亚洲特黄一级 | 一区二区在线| 成人中文字幕在线播放| 青娱乐精品在线视频| 成年人看片网站| 91麻豆国产福利精品| 制服丨自拍丨欧美丨动漫丨| 亚洲主播在线播放| 欧美国产一级片| 精品国产乱码久久久久久免费| 九九在线视频| 色综合久久悠悠| 欧美国产日韩电影| 国产精品久久波多野结衣| 国产一区二区精品福利地址| 欧美另类videos| 奶水喷射视频一区| 超碰人人cao| 欧美激情一二三区| 日本熟妇毛耸耸xxxxxx| 欧美日韩国产一级| 日产精品久久久久久久性色| 久久成人这里只有精品| 3d性欧美动漫精品xxxx软件| 国产精品免费视频一区二区| 成人在线免费视频观看| 日本丰满少妇xxxx| 国产在线乱码一区二区三区| 91久久免费视频| 亚洲国产aⅴ天堂久久| 一区二区国产欧美| 亚洲欧美中文在线视频| 久久一卡二卡| 91影院在线免费观看视频| 国产综合久久久| 91视频 -- 69xx| 成年人国产精品| 久久免费视频精品| 欧美精品久久一区| av在线女优影院| 日韩av日韩在线观看| 欧洲亚洲成人| 99在线免费视频观看| 国产精品一区二区在线观看网站| 亚洲一二三四视频| 91黄色在线观看| 欧美女v视频| 欧美一级视频在线观看| av一级亚洲| 日韩在线视频在线| 国产高清在线观看免费不卡| 黄色片网站在线播放| 欧美影院一区二区| 搞黄视频免费在线观看| 欧美在线一区二区三区四| 牛牛影视一区二区三区免费看| 女人被男人躁得好爽免费视频| 国产剧情av麻豆香蕉精品| 欧美做爰啪啪xxxⅹ性| 欧美日韩一区高清| www黄在线观看| 国产日韩欧美自拍| 97在线精品| 国产永久免费网站| 亚洲欧洲无码一区二区三区| 伊人精品一区二区三区| 日日骚久久av| 亚洲精品大全| av动漫在线播放| 成人网男人的天堂| 中文字幕第15页| 亚洲人成77777在线观看网| 色8久久影院午夜场| 亚洲精品一区二区三区樱花 | 欧美日韩中文在线观看| 色猫av在线| 国产精品成人观看视频国产奇米| 成人激情开心网| 色综合五月婷婷| 亚洲综合色网站| 姝姝窝人体www聚色窝| 欧美中文字幕在线| 成人黄色小视频| 中文字幕剧情在线观看| 亚洲制服丝袜av| 亚洲人在线观看视频| 日本精品性网站在线观看| 欧美偷拍综合| 欧美xxxxxbbbbb| 午夜精品在线视频一区| 黄色在线视频观看网站| 国产免费一区二区三区在线观看| 欧美~级网站不卡| 在线精品一区二区三区| 91成人在线免费观看| 日本免费在线视频| 国产伦精品一区二区| 天堂va蜜桃一区二区三区| 国产男女猛烈无遮挡在线喷水| 精品国产一区二区三区久久久蜜月| 国产777精品精品热热热一区二区| 日本精品一区二区三区高清 久久 日本精品一区二区三区不卡无字幕 | 天堂网视频在线| 精品国产一区二区三区久久狼5月 精品国产一区二区三区久久久狼 精品国产一区二区三区久久久 | 日本久久高清视频| 成人av中文字幕| 中文字幕+乱码+中文乱码91| 久久91精品国产| 精品日韩在线| 国产精品嫩草69影院| 一本大道av伊人久久综合| 国产网友自拍视频导航网站在线观看| 国产视色精品亚洲一区二区| 蜜桃av一区二区| 国产精品18p| 日韩在线免费观看视频| 国产成人精品亚洲线观看| 日本a√在线观看| 亚洲成a人v欧美综合天堂下载 | 欧美激情视频一区| 精品视频网站| 999精品免费视频| 制服丝袜av成人在线看|