併發包總結

1 Collections是什麼?collections是集合類的一個工具類,該類提供了一系列的靜態方法,用於對集合元素進行排序、搜索以及線程安全等各種操作

2 Collections方法之sort

 

AbstractSequentialList 接口?是list接口的基礎實現類,繼承自abstractList,不過與其功能相反,abstractList表示隨機訪問元素的列表,AbstractSequentialList表示順序訪問元素的列表,改寫了abstractList中獲取元素和修改元素的實現,通過ListIterator完成元素的增刪改查。

9 linkedList基於雙向鏈表實現list和Deque(隊列)兩個接口,允許元素爲空,當做deque使用時不能插入null元素,非同步的,

9 queue接口?三個實現類1concurrentLinkedqueue;2blockingQueue;3deque;繼承自collection接口,表示一個先進先出隊列,所有的新元素都插入到隊尾,從隊首獲取元素,共有6個核心方法。Add和offer表示添加元素到隊尾,remove和poll表示移出並返回隊首的元素,element和peek表示返回隊首的元素但是不移除,前者在當前操作(添加或者移除)失敗時會拋出異常,而peek不會,只會返回null或者false。

 

10 collections 之deque三個實現類1Arraydeque,2linkedlist;3blockingDeque;返回一個從左到右初始化的新deque對象(使用append()),其中包含來自iterable的數據,如果未指定iterable,則new deque爲空,deque是堆棧和隊列的泛化是雙端隊列double-ended-queue的縮寫),deque支持線程安全的,內存高效附加,從deque的任何一邊彈出(pop),在任何方向上的O(1)性能大致相同。 如果未指定maxlen或爲none,deques可能會增長到任意長度,否則deque被限制到制定的最大長度。一旦有界長度deque滿了,當添加新項時,將從另外一端丟棄響應數量的項。有界長度deque提供了與unix中的tail過濾器類似的功能。他們還可以用於跟蹤僅對最近的活動感興趣的事物和其他數據池。Queue,操作隊列兩端元素的方法都有兩種形式,一種是操作失敗拋出異常,一種是返回null或者false,且都不支持插入null元素。

11 deque方法? Append(x)  //在deque的右邊加上x ;appendleft(x)  //在deque的左邊加上x ;clear(x) 刪除deque中的所有元素,讓他的長度變爲0; count(x)  //計算deque中的元素x的個數; extend(iterable) //通過添加來自iterable參數的元素來擴展deque的右側;

Extendleft(iterable)  //通過添加iterable元素來擴展deque的左側(左對齊序列的結果顛倒了可迭代參數中元素的順序)。 Pop()  //從deque的右側刪除並且返回一個元素,如果不存在元素則引發一個indexError ;popleft() //從deque的左側刪除並返回一個元素; remove(value)  //刪除第一個出現的值,如果沒有找到,引發valueError; reverse() //將deque的元素反向放置, rotate(n=1) //向右旋轉deque n個步驟,如果n是負的 向左旋轉,當deque不爲空時,向右旋轉一步等價於d.appendleft(d.pop()),向左旋轉一步 等價於d.append(d.popleft()); 

12 deque與堆棧的比較?  如果嚴格禁止調用insertLeft()removeLeft()方法(或禁用右段的操作),雙端隊列功能就和一樣。禁止調用insertLeft()removeRight()(或相反的另一對方法),它的功能就和隊列一樣了,此接口擴展了 Queue 接口。 

13 arrayDeque接口?是基於數組的deque接口實現類,內存存儲結構簡單,當需要FIFO隊列,LIFO隊列或者STACK時,推薦優先使用ArrayDeque,ArrayDeque是線程不安全的,會自動擴容,

14 阻塞隊列blockingQueue的實現原理?它有4組不同的方法用於插入、移除以及對隊列中元素進行檢查。如果請求的操作不能得到立即執行的話,每個方法的表現也不同。

 

拋異常

特定值

阻塞

超時

插入

Add(o)

offer (o)

Put(o)

Offer(o,timeout,timeUnit)

移除

Remove(o)

Poll(o)

Take(o)

Poll(timeout,timeUnit)

檢查

Element(o)

Peek(o)

 

 

blockingQueue 中插入null會拋異常。

15 BlockingQueue的實現類?1 arrayBlockingQueue是一個有界的阻塞隊列,其內部實現是將對象放到一個數組裏,有界意味着它不能夠存儲無限多數量的元素,它有一個能夠存儲元素數量的上限,在初始化的時候設定這個上限,但之後就無法對這個上限進行修改了。2DelayQueue 對元素進行持有直到一個特定的延遲到期,注入其中的元素必須實現Delayed接口。3 linkedBlockingQueue 內部以一個鏈式結構(鏈式節點)對其元素進行存儲,如果需要的話,這一鏈式結構可以選擇一個上線,如果沒有定義上線,將使用Integer.MAX_VALUE作爲上限。4 priorityBlockingQueue是一個無界的併發隊列,它使用了和類priorityQueue一樣的排序規則。你無法向這個隊列中插入null值,所有插入到priorityBlockingQueue的元素必須實現comparable接口,因此該隊列中元素的排序就取決於你自己的comparable實現。5  SynchronousQueue 是一個特殊的隊列,它內部同時只能容納單個元素,如果該隊列已有一元素的話,試圖向隊列中插入一個新元素的線程將會阻塞,直到另一個線程將該元素從隊列中抽走。同樣,如果該隊列爲空,試圖向隊列中抽取一個元素的線程將會阻塞,直到另一個線程向隊列中插入一條新的元素。。據此,把這個類稱作一個隊列顯然是誇大其詞了,它更像一個匯合點。

16 BlockingQueue阻塞隊列原理?阻塞隊列實現阻塞同步使用的就是 lock鎖的多條件阻塞控制。使用BlockingQueue封裝了根據條件阻塞線程的過程,而我們不用關心繁瑣的await/signal操作了,

 

17 BlockingQueue接口的實現類?1 arrayblockingQueue ;2 delayQueue;3linkedBlockingQueue;4priorityBlockingQueue;5synchronizedQueue ;6transferQueue

18 arrayblockingQueue 的底層實現原理?是數組實現的線程安全的有界的阻塞隊列,可以按照FIFO(先進先出)原則對元素進行排序,線程安全是指arrayBlockingQueue內部通過“互斥鎖”保護競爭資源,實現了多線程對競爭資源的互斥訪問,有界指的是 arrayBlockingQueue對應的數組是有界限的。阻塞隊列是指多線程訪問競爭資源時,當競爭資源已被某線程獲取時,要獲取該資源的線程要阻塞等待。在創建arrayBlockingQueue對象時必須制定容量大小,默認情況下是非公平競爭的,它內部通過Object[]數組保存數據的,arrayBlockingQueue和reentrantLock是組合關係,arrayBlockingQueue裏面包含了一個reentrantLock對象,reentrantLock是可重入的互斥鎖。arrayBlockingQueue就是根據reentrantLock互斥鎖實現多線程對共享資源的訪問;arrayBlockingQueue和Condition也是組合關係,arrayBlockingQueue中包含了兩個Condition對象(notEmpty和notFull)。使用通知模式實現,所謂通知模式指的是:當生產者往滿的隊列裏面添加元素的時候,會阻塞生產者(調用condition notFull.await()進行等待),當消費者消費了一個隊列中的元素後,會通知(調用condition notfull.signal()方法喚醒生產者),生產者當前隊列可用。反之,當消費者消費的時候,發現隊列是空的,則消費者會被阻塞(通過Condition的notEmpty.await()進行等待)當生產者插入了隊列中的一個元素後,則會調用notempty.Signal()喚醒消費者繼續消費。

19 arrayblockingQueue的方法列表?

arrayblockingQueue(int capacity)創建一個帶有給定的容量和默認訪問策略的xxx

arrayblockingQueue(int capacity,boolean fair)帶有給定的容量和指定訪問策略的xxx

Boolean add(E e)將指定元素插入隊列的尾部,成功返回true,否則拋異常

Void clear() 自動移除此隊列中的所有元素,

Boolean contains(object o)如果此隊列包含指定的元素,返回true

Element() 獲取隊列首元素,若獲取成功,則返回首元素,否則拋異常

Offer(E e) 將元素e插入到隊列末尾,如果插入成功,則返回true,如果插入失敗則返回false

Peek(E e)獲取隊首元素,若成功,則返回隊首元素,否則返回null。

Put(E e) 用於隊列尾部存入元素,如果隊滿則等待,

Take()用於從隊首取出元素e,如果隊列爲空則等待。

在構造函數中維護了一個數組來保存阻塞隊列,fair是可重入的獨佔鎖(reentrantlock),notEmpty/notFull是鎖的兩個Condition條件。說明:lock的作用是提供獨佔鎖機制,來保護競爭資源,而condition是爲了更精細的對鎖進行控制,但是依賴於lock,通過某個條件對多線程進行控制。NotEmpty表示鎖的非空條件,當某線程想從隊列中獲取數據的時候,而此時隊列中的數據爲空,則該線程通過notEmpty.await()方法進行等待;當其他線程向隊列中插入元素後,就調用notEmpty.signal()方法進行喚醒之前等待的線程。同理,notfull表示鎖滿的條件,當某個線程向隊列中插入元素,而此時隊列已滿,該線程等待,即阻塞通過notFULL.await()方法,其他線程從隊列中取出元素後,就喚醒該等待的線程,這個線程調用notFULL.signal()方法。在添加元素時,如果隊列滿了就要調用await()方法。

20 delayqueue ?delayqueue是一個沒有邊界的blockingqueue實現,加入其中的元素必須實現delayed接口,當生產者線程調用put之類的方法加入元素時,會觸發delayed接口中的compareTo方法進行排序,也就是說隊列中元素的順序是按到期時間排序的,而非他們進入隊列的順序。排在隊列頭部的元素是最早到期的,越往後到期時間越晚。消費者線程查看隊列頭部的元素,注意不是取出,然後調用元素的getDelay方法,如果此方法返回的值小於等於0,則消費者線程會從隊列中取出此元素並進行處理。如果getDelay方法返回的值大於0,則消費者線程wait返回的時間值後,再從隊列頭部取出元素,此元素應該已經過期。Delayqueue是leader-follower模式的變種,消費者線程處於等待狀態時,總是等待最先到期的元素,而不是長時間的等待。消費者線程儘量把時間花在處理任務上,最小化空等的時間,以提高線程的利用效率。因爲隊列是沒有邊界的,向隊列中添加元素不會阻塞,添加操作相對簡單。消費者線程1查看了頭部元素後,發現還要2s纔到期,於是它進入等待狀態,2s後醒來,等待頭部元素到期的線程成爲leader線程。此時另外的消費線程2都處於待命狀態,他們不等待隊列中的非頭部元素,當消費者線程1拿到時間到期的對象以後,會向消費者線程2發送signal信號,這個時候消費者線程2會結束待命狀態而進入等待狀態。消費者線程1已經拿到之前時間到期的對象後,從等待狀態變成處理狀態,處理它取到的對象。同時向消費者線程2(還有其他線程3.。。。)發送signal。消費者線程2與其他消費者線程會爭奪領導權,如果消費者線程2進入等待狀態,成爲leader線程,等待2s後,另外一個對象到期。。。消費者線程1處理完對象後就變成了待命狀態。但是如果一個對象馬上到期,而消費者線程都在處理其他對象,此時馬上到期的對象的處理一定會延期。

21 delayqueue的應用場景?定時任務調度。

22 linkedeBlockingQueue 是一個使用鏈表完成隊列操作的阻塞隊列,鏈表是單向鏈表,而不是雙向鏈表,內部使用放鎖和拿鎖,這兩個鎖實現阻塞,因爲由兩個鎖,存在競態條件,使用atomicInteger,拿鎖和放鎖都是使用reentrantlock,正因爲有兩個鎖,添加數據和刪除數據是可以並行進行的,當然添加數據和刪除數據的時候只能有一個線程各自執行。添加數據的方法有add、offer和put;

23 LinkedBlockingqueue與arrayblockingqueue中添加元素的底層實現原理的區別?arrayblockingqueue中放入數據阻塞的時候,需要消費數據才能喚醒,但是LinkedBlockingqueue中放入數據阻塞的時候,因爲它內部有2個鎖,可以並行執行放入數據和消費數據,不僅在消費數據的時候進行喚醒插入阻塞線程,同時也在插入數據的時候(如果容量沒滿),也會喚醒插入阻塞的線程。

24 阻塞隊列priorityBlockingQueue實現原理?該阻塞隊列每次取出的都是最小的對象,可以滿足一定的實際場景。阻塞隊列priorityBlockingQueue從不阻塞寫線程,而當隊列元素爲空時,會阻塞讀線程的讀取,當然也有非阻塞的方法(poll)。該阻塞隊列適用於讀多於寫的場景,不然寫線程過多或導致內存消耗過大,影響性能。讀線程在隊列爲空時阻塞,當隊列滿時,寫線程不會阻塞,而會嘗試去擴容,擴容成功就繼續向阻塞隊列寫入數據。當隊列爲空時,讀線程會阻塞等待,直到隊列不爲空,被寫線程喚醒。阻塞隊列每次取出的都是最大/最小的對象,而底層的存儲結構正是堆存儲(每一個父節點需要大於/小於每一個子節點),所以每次向阻塞隊列添加的時候,根據元素的大小,調整其在堆中的位置,不需要對所有元素排序,只需要對父子節點排序。這樣每次從阻塞隊列中取出元素時,直接取出堆頂元素,即最大/小值,然後重新調整堆。

25阻塞隊列priorityBlockingQueue的擴容機制?當阻塞隊列滿時,寫線程會嘗試擴容(擴增old+2或者old/2),注意,寫線程擴容的時候會先釋放獨佔鎖,並獲取一個擴容獨佔鎖(此鎖僅用於擴容),這樣做的目的是提高讀線程的吞吐量,擴容的本質其實就是新建一個更大的object數組,然後把阻塞隊列中的原阻塞隊列引用替換成新的數組。

26阻塞隊列priorityBlockingQueue的排序?因爲阻塞隊列使用的是對存儲結構,那麼就需要對父子節點進行排序,所以需要阻塞隊列存儲的元素實現comparable接口,或者在新建阻塞隊列priorityBlockingQueue的時候提供比較器。

27 公平模式下的synchronousQueue的底層原理?有多個生產者,可以併發生產產品,把產品置於入隊列中,如果隊列滿了,生產者就會阻塞;有多個消費者,併發從隊列中獲取產品,如果隊列空了,消費者就會阻塞;它是一個隊列,但是他的特別之處是它的內部沒有容器,一個生產線程,當它生產產品的時候,如果當前沒有人想要消費產品(當前沒有線程執行take),此生產線程必須阻塞,等待一個消費線程調用take操作,take操作會喚醒該生產線程,同時消費線程會獲取生產線程的產品(數據傳遞),這樣的過程稱爲一次配對過程(當然也可以先take後put),可以認爲這是一種線程與線程間一對一傳遞消息的模型。不像arrayBlockingQueue、linkedBlockingDeque之類的阻塞隊列依賴AQS實現併發操作,synchronousQueue直接使用CAS實現線程的安全訪問。隊列的實現策略通常分爲公平模式和非公平模式,在公平模式下,底層的實現使用的是transferQueue這個內部隊列,它有一個head和tail指針,用於指向當前正在等待匹配的線程節點。初始化時隊列爲空,當執行put(1)時,由於當前沒有配對的消費線程,所以put線程入隊列,自旋一小會後睡眠等待,接着線程執行另外一個put(2)操作,如上,此時有兩個元素1和2;這時來了一個take1線程,執行了take操作,因爲tail指向put2線程,所以put2線程跟take1線程配對了(一個put對一個take),此時take1線程不需要入隊,但是要喚醒的線程並不是put2,而是put1,因爲現在講的是公平策略,誰先入隊,誰就優先被喚醒消費(把這個線程喚醒,調用run方法使用掉),因爲隊尾匹配,而隊頭出隊!執行後put1線程被喚醒,take1線程的的take方法返回了1(put1線程的數據),這樣就實現了線程間的一對一通信,這時候內部狀態裏還有put2線程在睡眠,最後再來一個線程take2,執行take操作,這時候只有put2線程在等候,而且兩個線程匹配上了,線程put2倍喚醒,take2線程take操作返回了2(線程put2的數據)這時候隊列就回到了起點。

28非公平模式下synchronousQueue的底層原理?使用的是transferStack,一個棧,實現中用head指針指向棧頂,接着看實現模型:線程put1執行put(1)操作,由於當前沒有配對的消費線程,所以put1線程入棧,自旋一小會睡眠等待,然後再執行put2線程入棧,這時候來了一個take1線程,執行了take操作,發現棧頂爲put2線程,匹配成功,但是實現會先把take1線程入棧,然後take1線程循環執行匹配put2線程邏輯,一旦發現沒有併發衝突,就會把棧頂指針直接指向put1線程。最後再來個take2線程。。。最後棧變爲空,恢復初始狀態。之所以是非公平,是因爲先入棧的後匹配。SynchronousQueue由於其獨有的線程—配對通信機制,在大部分平常開發中,可能都不會用到,但線程池技術中會有所使用,內部沒有使用AQS而是使用CAS。

29 transferQueue接口的實現類LinkedTransferQueue併發容器底層實現原理?LinkedTransferQueue是一個底層數據結構由鏈表實現的無界阻塞隊列,它與synchronousQueue中公平模式的實現Transferqueue及其相似,LinkedTransferQueue裏面存儲的也是操作而不是數據元素。Sfer方法是LinkedTransferQueue中最核心的一個方法,隊列中既可以存放take操作,也可以存放put操作,但是隊列中不能同時存在兩種不同的操作,因爲不同的操作會觸發隊列進行配對(操作出隊),當隊爲空時,如果一個線程執行take操作,此時隊列中是沒有對應的put操作與之匹配的,那麼這個take操作就會入隊(如果有就會匹配然後出隊。。。),同時阻塞(也可能自旋)執行這個操作的線程以等待匹配操作的到來,同理,空隊列時,如果來的是一個put操作,那麼這個put操作也要入隊阻塞等待匹配的take操作的到來。而當隊列不爲空時(假設隊列中都是take操作),某一個線程執行put操作,此時隊列檢測到來了一個與隊列中存放的操作匹配的操作,那麼就會將隊首操作與到來的操作進行匹配,匹配成功就會喚醒隊首操作所在的線程,同時將已經匹配過的操作移除出隊,而若是某一線程執行的是與隊裏中相同的操作,那麼就將該操作直接添加到隊尾。Xfer方法直接包含了所有功能,不僅add、put、offer,還有poll、take、transfer、tryTransfer。

30 copyOnWrite容器(併發容器)是一種用於程序設計中的優化策略,基本思路是:從一開始大家都在共享同一個內容,當某個人想要修改這個內容的時候,纔會真正把內容拷貝出去形成一個新的內容,然後再修改,這是一種延時懶惰策略。併發包中的copyonWriteArrayList和copyonWriteArraySet容器都是使用copyOnWrite機制實現。copyOnWrite容器即寫時複製的容器,當我們往一個容器添加元素的時候,不直接往當前容器添加,而是先將當前容器進行拷貝,複製出一個新的容器,然後往新的容器裏添加元素,添加完元素後,再將原容器的引用指向新的容器,這樣的好處是可以對copyonWrite容器進行併發的讀,而不需要加鎖,因爲當前容器不會添加任何元素。所以copyonWrite是一種讀寫分離的思想,讀和寫不同的容器,最終一致性以及使用另外開闢空間的思路來解決併發衝突的思想。

31 collections 之copyonWriteArrayList 底層實現原理?是synchronizedList的替代方案,是一個ArrayList的線程安全的變體,底層使用數組來存放元素,初始化的時候只有一個容器,很長一段時間這個容器數據沒有發生變化,大家(多個線程)都是讀取同一個容器中的數據,此時讀取的數據都是唯一的、一致的、安全的,但是後來有人往裏面添加一個數據,這個時候copyonWriteArraylist底層實現添加的原理是先拷貝出一個容器,再往新的容器裏添加這個新的數據,最後把新的容器的引用地址賦值給了之前那個舊的容器地址,但是在添加這個數據的期間,其他線程如果去讀取數據,仍然是讀取到舊的容器裏的數據。在add添加的時候是需要加鎖的,否則多線程寫的時候會拷貝出多個。

32 copyonWrite的優缺點?優點:1解決開發工作中的多線程併發問題;缺點:1內存佔用問題(在寫操作的時候,內存裏同時駐紮兩個對象的內存,舊的對象和新寫入的對象,注意:在複製的時候只是複製容器裏的引用),針對內存佔用問題,可以通過壓縮容器中的元素的方法來減少大對象的內存消耗,或者不使用copyonWrite容器,改爲其他併發容器,如concurrentHashMap;2數據一致性問題,copyonWrite容器只能保證數據的最終一致性,不能保證數據的實時一致性,所以如果你希望寫入的數據能夠立馬讀取到,請不要用copyonWrite容器。

33 copyonWrite的總結?1適用於讀多寫少的場景,2在併發操作容器對象時不會拋出ConcurrentModificationException異常,並且返回的元素與迭代器創建的元素是一致的,3在需要併發操作list對象的時候,優先使用copyonWriteArrayList,

34 copyonWriteArraySet 的底層實現原理?不能添加重複的元素,相比較copyonWriteArrayList, Set集合沒有按索引直接獲取或修改或添加或刪除的方法(eg:get(int index),add(int index))copyonWriteArraySet常用的方法如下:1構造方法copyonWriteArraySet();2添加元素 add(E)方法;3刪除對象 remove(E)方法,4遍歷多有對象 Iterator(),注意:以上方法的實現底層中都是對copyonWriteArrayList的操作,(CopyOnWriteArraySet每次add都要遍歷數組,性能要低於CopyOnWriteArrayList

35 ConcurrentSkipListSet 的底層實現原理?1 ConcurrentSkipListSet的底層是通過ConcurrentNavigableMap來實現的,是一個有序線程安全的集合,是基於元素的自然排序或者通過比較器確定的順序;2源碼中,跟通過Map實現的set基本一致,多了一些取最近元素的方法;

36 concurrentMap接口?concurrentHashMap實現類 和 concurrentNavigatableMap接口(的concurrentSkipListMap實現類)

37 concurrentHashMap的底層實現原理?1底層數據結構與hashMap相同,都是數組+桶(鏈表/紅黑樹)構成,桶中的數據可能是鏈表也可能是紅黑樹,紅黑樹提高查找效率;2相對比hashMap而言,它是線程安全的;3擁有大量的內部類,Node類主要用於存儲具體鍵值對;traverser類用於遍歷操作;collectionView抽象類用於定義視圖操作;segment類用於序列化。

38 concurrentHashMap爲何比HashMap高效?HashMap之所以低效,是因爲所有訪問HashMap的線程都爭奪一把鎖,而concurrentHashMap的設計理念是:容器中有很多把鎖,每一個鎖控制容器中的一部分數據,那麼當多個線程訪問容器裏面不同部分的數據時,線程之間就不會存在鎖的競爭,提高了併發的效率,即使用分段鎖技術。

39 concurrentskipListMap的底層實現原理之跳錶?1瞭解skipList,即跳錶,一般的鏈表由於無法進行隨機訪問,所以查找性能是log(n),所以在普通鏈表的基礎上增加層次結構的功能方便查找,比如把某幾個元素提取出來作爲一級索引,這樣搜索的時候就可以減少比較次數了,Node節點有兩個指針,一個指向同一鏈表中的下一個元素,一個指向下面一層的元素;2 Node的所有方法使用了CAS方法,因此是線程安全的。3跳錶的插入採用隨機的方式來決定該元素要佔據的層數K,4最底層的鏈表包含所有的元素,5每一層都是一個有序的鏈表,默認是升序,也可以根據創建映射時所提供的comparator進行排序,

40 concurrentskipListMap的底層實現原理? 調用Size方法時,由於多個線程可以同時對映射表進行操作,所以映射表需要遍歷整個鏈表才能返回元素個數;

41多個Map的性能比較(TreeMapHashMapConcurrentSkipListMap)?1treeMap基於紅黑樹(自平衡二叉查找樹)實現的,時間複雜度爲Ologn),treeMap取出來的是排序後的鍵值對,插入和刪除需要維護平衡會犧牲一些效率;2hashMap是基於散列表實現的,時間複雜度平均能達到O1),單線程環境下,hashMap比其他兩個在插入和查找上有很大優勢;3concurrentSkipListMap是基於跳錶實現的,時間複雜度能達到Ologn),skipList默認是按照key升序的,適合大規模數據併發訪問,與其他有鎖機制的數據結構相比有優勢;

42 Future 接口?實現類/接口有:1RunnableFuture接口、2ScheduledFuture接口、3FockJoinTask實現類,Future接口是一個泛型接口,返回的是callablecall方法執行的結果,此接口方法如下:1 cancel()方法取消任務的執行,參數指定是否立即中斷任務的執行;2isCancelled()任務是否已經取消,任務正常完成前將其取消,則返回true3isDone任務是否已經完成,如果任務正常終止、異常或取消,都將返回true4 V  get()throws InterruptedException等待任務執行結果,然後獲取V類型的結果,Future表示異步計算結果,它提供了檢查計算是否完成的方法,以等待計算的完成,並獲取計算的結果,計算完成後只能使用get方法獲取結果,如有必要,計算完成前可以阻塞此方法,取消則由cancel方法執行,Future就是對具體的runnable或者callable任務的執行結果進行取消、查詢是否完成、獲取結果。必要時可以通過get方法獲取執行結果,該方法會阻塞直到任務返回結果。總結一句:Future提供的功能1判斷任務是否完成,2能夠中斷任務,3能夠獲取任務執行結果。

43 RunnableScheduledFuture

44 Future接口的實現類futureTask類?futureTask類結合callable接口使用,當我們把callable接口中的call方法交給線程執行時,我們可以繼續做其他事情,futureTask類可以獲取call方法返回值,它的作用就是控制callablecall方法的執行過程。其核心思想就是:比如有一個方法f,計算過程可能非常耗時,等待f返回顯然是不明智的,可以在調用f的時候,立馬返回一個Future,可以通過Future這個數據結構去控制方法f的計算過程。

45 executor接口?通常使用它方便地生產各種類型的線程池,主要方法有三種1創建一個單線程的線程池;2創建一個固定大小的線程池;3創建一個可緩存的線程池,調用executer()方法可以重用緩存中的線程,適用於很多短期異步任務的環境。

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章