Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 面試題總結(二)

Android 面試題總結(二)

編輯:關於Android編程

前言

筆者最近離職找工作快兩周了,這段時間陸陸續續也見識了北上廣這邊跟西部城市對待技術理念的差異和學習深度.俗話說:知恥而後勇,在經歷了面試被虐得體無完膚的過程後,我也找到了作為一名開發者應有的職業素養和今年的發展規劃. 俗話也說的好,王侯將相寧有種乎,我不信我從今天開始認認真真對待每一個技術細節,認真刷題.,在深圳這座城市沒有我的立足之地. 好了,雞湯和廢話也不多說了,依舊記錄今日面試的題目.

正文

含義:一個對象已經不需要再使用了,但是因為其他的對象持有該對象的引用,導致它的內存不能被回收.
危害:只有一個,那就是虛擬機占用內存過高,導致OOM(內存溢出),程序出錯.
內存洩露的主要問題可以分為以下幾種類型:
1.靜態變量引起的內存洩露:
在java中靜態變量的生命周期是在類加載時開始,類卸載時結束.換句話說,在android中其生命周期是在進程啟動時開始,進程死亡時結束.所以在程序的運行期間,如果進程沒有被殺死,靜態變量就會一直存在,不會被回收掉.如果靜態變量強引用了某個Activity中變量,那麼這個activity就同樣也不會被釋放,即便是該activity執行了onDestroy.
解決方案:
1.尋找與該靜態變量生命周期差不多的替代對象.
2.若找不到,將強引用方式改成弱引用.
案例:單例引起的context內存洩露
public static IMManager getInstance(Context context) {
        if (mInstance == null) {
            synchronized (IMManager.class) {
                if (mInstance == null)
                    mInstance = new IMManager(context);
            }
        }
        return mInstance;
    }

當調用getInstance時,如果傳入的context是Activity的context。只要這個單例沒有被釋放,這個Activity也不會被釋放。
解決方案:傳入Application的context.
2.非靜態內部類引起的內存洩露:
在java中,創建一個非靜態的內部類實例,就會引用它的外圍實例.如果這個非靜態內部類實例做了一些耗時的操作.就會造成外圍對象不會被回收,從而導致內存洩露.
解決方案:
1.將內部類變成靜態內部類
當將內部類變成靜態內部類後,便不再持有外部類對象的引用,導致程序不允許你在handler中操作activity的對象了,因此我麼需要在handler中增加一個對A/ctivity的弱引用(WeakReference);
注:為什麼使用靜態內部類就不會造成內存洩露了?
答:靜態內部類不會持有對外部對象的引用
2.如果有強引用Activity中的屬性,則將該屬性的引用方式改為弱引用.
使用WeakReference包裝該對象.
3.在業務允許的情況下,當activity執行onDestory時,結束這些耗時任務

static class MyHandler extends Handler {
    WeakReference mActivityReference;

    MyHandler(Activity activity) {
        mActivityReference= new WeakReference(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        final Activity activity = mActivityReference.get();
        if (activity != null) {
            mImageView.setImageBitmap(mBitmap);
        }
    }
}

3.資源未關閉引起的內存洩露
當使用了BroadcastReceiver\Cursor\Bitmap等資源的時候,當不需要使用時,需要及時釋放掉,若沒有釋放,則會引起內存洩露.

4.**增加:在使用Bitmap時,出現內存溢出的解決方案:**1.調用系統的GC回收,System.gc();2.壓縮圖片質量大小.

小結

雖然靜態類與非靜態類之間的區別並不大,但是對於Android開發者而言卻是必須理解的.至少我們要清楚,如果一個內部類實例的生命周期比Activity更長,那麼我們千萬不要使用非靜態的內部類.最好的做法是,使用靜態內部類,然後在該類裡面使用弱引用來指向所在的Activity

2.Java基礎之弱引用\強引用\軟引用\虛引用
強引用(StrongReference):是使用最普遍的引用.如果一個對象具有強引用,那GC回收器絕不會回收它.

    Object o=new Object();   //  強引用  
    public void test(){  
        Object o=new Object();  
        // 省略其他操作  
    }  

當內存不足時,java虛擬機寧願拋出OutOfMemoryError錯誤,使程序異常終止,也不會靠隨意回收具有強引用的對象來解決內存不足的問題.如果不使用時,要通過如下方式來弱化引用.

在方法內部有一個強引用,這個引用保存在棧中,而真正得引用內容(Object )保存在堆中.當這個方法運行完成後,就會推出方法棧,則引用內容的引用不存在,這個Object會被回收.

但是如果這個o是全局的變量時,就需要在不用這個對象時復制為null,因為強引用不會被垃圾回收。
軟引用(SoftReference): 如果一個對象只具有軟引用,則內存空間足夠,垃圾回收器就不會回收它;如果內存空間不足了,就會回收這些對象的內存。只要垃圾回收器沒有回收它,該對象就可以被程序使用。軟引用可用來實現內存敏感的高速緩存。

    String str=new String("abc");                                     // 強引用  
    SoftReference softRef=new SoftReference(str);     // 軟引用    

軟引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果軟引用所引用的對象被垃圾回收器回收,Java虛擬機就會把這個軟引用加入到與之關聯的引用隊列中。
弱引用:
弱引用與軟引用的區別在於:只具有弱引用的對象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的內存區域的過程中,一旦發現了只具有弱引用的對象,不管當前內存空間足夠與否,都會回收它的內存。不過,由於垃圾回收器是一個優先級很低的線程,因此不一定會很快發現那些只具有弱引用的對象。

    String str=new String("abc");      
    WeakReference abcWeakRef = new WeakReference(str);  
    str=null;    

當你想引用一個對象,但是這個對象有自己的生命周期,你不想介入這個對象的生命周期,這時候你就是用弱引用。
虛引用(PhantomReference):
“虛引用”顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用並不會決定對象的生命周期。如果一個對象僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。
虛引用主要用來跟蹤對象被垃圾回收器回收的活動。虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用隊列 (ReferenceQueue)聯合使用。當垃圾回收器准備回收一個對象時,如果發現它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之 關聯的引用隊列中。
這裡寫圖片描述vcv7w8eho9LytMujrHN0YXRpY7bUz/O/ydLU1NrL/LXEyM66zrbUz/O0tL2o1q7HsLfDzsqjrM7e0OjS/dPDyM66zrbUz/OhozxiciAvPg0KMS48c3Ryb25nPnN0YXRpY9Deys63vbeoOjwvc3Ryb25nPjxiciAvPg0KtbFzdGF0aWO52Lz819bQ3srOt723qMqxo6zV4rj2t723qL7Ns8bOqr6yzKy3vbeooaO+ssyst723qMr009rA4Lb4srvK9NPayrXA/bbUz/Oho8THw7S+ssyst723qMjnus69+NDQtffTw6O/v8nS1M2ouf3A4MP7Lre9t6jD+8C01rG907X308OjrNKyv8nS1M2ouf3KtcD9ttTP8y63vbeow/vAtLX308OhozxiciAvPg0KyrnTw3N0YXRpY7nYvPzX1tDeys61xLe9t6jU2sDgvNPU2LXEyrG68r7Nu+G809TYtb3E2rTm1tCho8rHsbvWuM/yy/nK9LXEwOC2+LK7ysfKtcD9oaM8YnIgLz4NCr/J0tS/tLP2o6zV4rKisrvKx7iyuMejrMbkyrW+ssyst723qNa7v8nS1LG70v6y2KOstviyu7/J0tS4srjHoaO1sXQxzqpQZXJzb27A4NDNyrGjrNTytffTw1BlcnNvbsDgtcS+ssyst723qKOs0vLOqr6yzKy3vbeo1rvK9NPa1eK49sDgo6y2+LWxdDLA4NDNzqpUZXN0MDLKsaOstffTw9fTwOC1xL6yzKy3vbeoo6y1sdfTwODDu9PQyrGjrLX308O4uMDgtcS3vbeoo6zV4r7NvdDX9rzMs9C4uMDgtcS3vbeowcuhozxiciAvPg0KMi48c3Ryb25nPnN0YXRpY9DeuMTK9NDUOjwvc3Ryb25nPjxiciAvPg0KtbFzdGF0aWPQ3srOyvTQ1Mqxo6zT68Dg0rvR+aOstrzKx9TawOC809TYyrG+zbzT1Ni1vcHLxNq05qGjPGJyIC8+DQozLjxzdHJvbmc+c3RhdGlj0N7Kzr/pPC9zdHJvbmc+PGJyIC8+DQq803N0YXRpY9Deys61xL/p0rK74cvm18XA4LXEvNPU2Lb4vfjI68TatOajrMv50tS/ydLU1NrV4sDvs/XKvLuv0rvQqb6yzKyzydSxseTBv6GjPGJyIC8+DQo0LjxzdHJvbmc+yrnTw3N0YXRpY9ei0uLKws/uOjwvc3Ryb25nPjxiciAvPg0KtbHA4LG70OnE4rv6vNPU2Mqxo6ywtNXVyfnD98uz0PLPyLrzs/XKvLuvc3RhdGljs8nUsdfWts66zXN0YXRpY9PvvuS/6TxiciAvPg0Kc3RhdGljy/nQ3srOtcS3vbeous2x5MG/1rvK9NPawOCjrMv509C21M/zubLP7aGjPGJyIC8+DQrU2nN0YXRpY8v50N7KzrXEt723qLrN0+++5L/p1tCyu8TcyrnTw7fHc3RhdGljs8nUsdfWts6hozxiciAvPg0KvrLMrLPJ1LGyu8rHttTP87XEzNjQ1KOs1rvKx86qwcvV0tK7uPbI3cnt1q60pqOsy/nS1NDo0qq3xbW90ru49sDg1tC2+NLRo6yw0SZsZHF1bzvIq77WseTBvyZyZHF1bzu3xdTaxNqyv8Dg1tC+zcrHusHO3tLi0uW1xMrCx+mjrMv50tQgsbu9+9a5PGJyIC8+DQrU2kphdmGyu8Tc1rG907ao0uXIq77WseTBv6OsysfNqLn9c3RhdGljwLTKtc/WtcQ8YnIgLz4NCtTaSmF2YdbQw7vT0GNvbnN0o6yyu8Tc1rG907ao0uWzo8G/o6zNqLn9c3RhdGljIGZpbmFswLTKtc/WPGJyIC8+DQo8c3Ryb25nPmZpbmFsILnYvPzX1jo8L3N0cm9uZz48YnIgLz4NCjEuPHN0cm9uZz5maW5hbLnYvPzX1rXEyrnTwzo8L3N0cm9uZz7S/dPDsb7J7bXEsrux5LrN0v3Tw9a4z/K1xLbUz/Oyu7HkoaM8YnIgLz4NCjxzdHJvbmc+0N7KzsDgOjxlbT4qPC9lbT48L3N0cm9uZz7I57n70ru49sDgsbvJ+cP3zqpmaW5hbKOs0uLOttfFy/yyu8Tc1NnFycn6s/bQwrXE19PA4KOssrvE3Nf3zqq4uMDgsbu8zLPQKqGj0vK0y9K7uPbA4LK7xNzNrMqxyfnD986qYWJzdHJhY3QgZmluYWy78tXfaW50ZXJmYWNlIGZpbmFstcShozxiciAvPg0KPHN0cm9uZz7Q3srOt723qCA6PC9zdHJvbmc+vau3vbeoyfnD986qZmluYWyjrL/J0tSxo9aky/zDx9TayrnTw9bQsruxu7jEseSho7G7yfnD986qZmluYWy1xLe9t6jSss2s0fnWu8TcyrnTw6OssrvE3NbY1Niho7WrysfX08Dgv8nS1LzMs9C4uMDgtcRmaW5hbLe9t6ihozxiciAvPg0KPHN0cm9uZz7Q3srOseTBvyA6PC9zdHJvbmc+se3Kvsr00NTWtbXa0ru0zrP1yry7r7rzsrvE3LG70N64xKGjZmluYWzK9NDUv8nS1NaxvdOz9cq8u6+78tTaubnU7Lqvyv3W0LP1yry7ry7I57n7yvTQ1MrH1rG907P1yry7r6Os1PLG5Na1srvE3LG7xuTL/Lqvyv0osPzAqLm51Oy6r8r9KdDeuMShozxiciAvPg0KPHN0cm9uZz7Q3srOt723qLLOyv0gOjwvc3Ryb25nPrLOyv3WtbK7xNyxu9DeuMQ8YnIgLz4NCjxzdHJvbmc+0N7Kzre9t6jW0LXEvtayv7Hkwb8gOjwvc3Ryb25nPiC+1rK/seTBv7G7tdrSu7TOs/XKvLuvuvOyu8TcsbvQ3rjEPGJyIC8+DQrXojrIzrrO1NppbnRlcmZhY2XA78n5w/e1xLPJ1LGx5MG/o6zErMjPzqpwdWJsaWMgc3RhdGljIGZpbmFsoaM8YnIgLz4NCjxzdHJvbmc+yrnTw2ZpbmFstcTS4tLlOjwvc3Ryb25nPjxiciAvPg0KtdrSu6Oszqq3vbeoJmxkcXVvO8nPy/gmcmRxdW87o6y3wNa5yM66zrzMs9DA4LjEseTL/LXEsb7AtLqs0uW6zcq1z9aho8novMazzNDyyrGjrMj0z6PN+9K7uPa3vbeotcTQ0M6q1Nq8zLPQxtq85LGjs9ayu7Hko6y2+MfSsru/ybG7uLK4x7vyuMTQtKOsvs2/ydLUssnIodXi1tbX9reooaM8YnIgLz4NCrXatv6jrMzhuN+zzNDy1rTQ0LXE0KfCyqOsvavSu7j2t723qMnos8lmaW5hbLrzo6yx4NLrxve+zb/J0tSw0bbUxMe49re9t6i1xMv509C199PDtrzWw8jrJmxkcXVvO8e2yOsmcmRxdW87tffTw8Dvo6jE2se2u/rWxqOpoaM8YnIgLz4NCjxzdHJvbmc+ZmluYWxsebnYvPzX1jo8L3N0cm9uZz48YnIgLz4NCtTa0uyzo7SmwO3KsczhuakgZmluYWxseSC/6cC01rTQ0MjOus7H5bP9stnX96GjyOe5+8XXs/bSu7j20uyzo6OsxMfDtM/gxqXF5LXEIGNhdGNoINfTvuS+zbvh1rTQ0KOsyLu687/Y1sa+zbvhvfjI6yBmaW5hbGx5IL/poaMgy/nS1Mu1ZmluYWxseb/pysfSu7aou+Gxu9a00NC1xKGjPGJyIC8+DQpmaW5hbGx5INPvvuS/6crH1NogdHJ5ILvy1d8gY2F0Y2gg1tC1xCByZXR1cm4g0+++5Naux7DWtNDQtcSho7j8vNPSu7DjtcTLtbeoysejrGZpbmFsbHkg0+++5L/p06a4w8rH1Nq/2NbG16rSxtPvvuTWrsew1rTQ0KOsv9jWxteq0sbT777ks/3ByyByZXR1cm4gzeKjrLu509AgYnJlYWsgus0gY29udGludWWhoyByZXR1cm4gus0gdGhyb3cgsNGzzNDyv9jWxsio16q9u7j4y/zDx7XEtffTw9Xfo6hpbnZva2Vyo6mjrLb4IGJyZWFrILrNIGNvbnRpbnVlILXEv9jWxsioysfU2rWxx7C3vbeoxNrXqtLGoaM8YnIgLz4NCjxzdHJvbmc+ZmluYWxpemUgt723qMP7Ojwvc3Ryb25nPjxiciAvPg0KZmluYWxpemWjqKOpt723qMrH1NrArLv4ytW8r8b3yb6z/bbUz/PWrsewttTV4rj2ttTP87X308O1xKGjPC9wPg0KPHA+NC48c3Ryb25nPkphdmG24M/fs8zP37PMs9ggLSDP37PMs9jUrcDtOjwvc3Ryb25nPjwvcD4NCjxwcmUgY2xhc3M9"brush:java;"> public interface Executor { void execute(Runnable command); }

Executors方便的創建線程池.
(1).newCachedThreadPool :該線程池比較適合沒有固定大小並且比較快速就能完成的小任務,它將為每個任務創建一個線程。那這樣子它與直接創建線程對象(new Thread())有什麼區別呢?看到它的第三個參數60L和第四個參數TimeUnit.SECONDS了嗎?好處就在於60秒內能夠重用已創建的線程。下面是Executors中的newCachedThreadPool()的源代碼: 

    //基本的無界值(如 Integer.MAX_VALUE),則允許池適應任意數量的並發任務
    public static ExecutorService newCachedThreadPool() {  
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue());  
        }  

(2).newFixedThreadPool:使用的Thread對象的數量是有限的,如果提交的任務數量大於限制的最大線程數,那麼這些任務將排隊,然後當有一個線程的任務結束之後,將會根據調度策略繼續等待執行下一個任務。下面是Executors中的newFixedThreadPool()的源代碼:  

    public static ExecutorService newFixedThreadPool(int nThreads) {  
          return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue());  
      }  

(3).newSingleThreadExecutor:就是線程數量為1的FixedThreadPool,如果提交了多個任務,那麼這些任務將會排隊,每個任務都會在下一個任務開始之前運行結束,所有的任務將會使用相同的線程。下面是Executors中的newSingleThreadExecutor()的源代碼: 

    public static ExecutorService newSingleThreadExecutor() {  
            return new FinalizableDelegatedExecutorService  
                (new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue()));  
        }  

(4).newScheduledThreadPool:創建一個固定長度的線程池,而且以延遲或定時的方式來執行任務。
ThreadPoolExecutor構造方法:

 public ThreadPoolExecutor(int corePoolSize,  //核心線程
                     int maximumPoolSize,  // 線程池維護的最大線程數量 
                     long keepAliveTime,  //線程池維護線程所允許的空閒時間
                     TimeUnit unit,  
                     BlockingQueue workQueue //// 阻塞隊列  ) {  
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,  
        Executors.defaultThreadFactory(), defaultHandler);  
}  

ExecutorService:為了解決執行服務的生命周期問題,Executor擴展了EecutorService接口,添加了一些用於生命周期管理的方法。

ThreadPoolExecutor線程池實現類:

    private final BlockingQueue workQueue;              // 阻塞隊列  
    private final ReentrantLock mainLock = new ReentrantLock();   // 互斥鎖  
    private final HashSet workers = new HashSet();// 線程集合.一個Worker對應一個線程  
    private final Condition termination = mainLock.newCondition();// 終止條件  
    private int largestPoolSize;           // 線程池中線程數量曾經達到過的最大值。  
    private long completedTaskCount;       // 已完成任務數量  
    private volatile ThreadFactory threadFactory;     // ThreadFactory對象,用於創建線程。  
    private volatile RejectedExecutionHandler handler;// 拒絕策略的處理句柄  
    private volatile long keepAliveTime;   // 線程池維護線程所允許的空閒時間  
    private volatile boolean allowCoreThreadTimeOut;  
    private volatile int corePoolSize;     // 線程池維護線程的最小數量,哪怕是空閒的  
    private volatile int maximumPoolSize;  // 線程池維護的最大線程數量  

處理任務的優先級為:

核心線程corePoolSize > 任務隊列workQueue > 最大線程maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務。 當池中的線程數大於corePoolSize的時候,多余的線程會等待keepAliveTime長的時間,如果無請求可處理就自行銷毀。

workQueue :線程池所使用的緩沖隊列,該緩沖隊列的長度決定了能夠緩沖的最大數量,緩沖隊列有三種通用策略:
(1) 直接提交,工作隊列的默認選項是 SynchronousQueue,它將任務直接提交給線程而不保持它們.
(2) 無界隊列,使用無界隊列(例如,不具有預定義容量的 LinkedBlockingQueue)將導致在所有 corePoolSize 線程都忙時新任務在隊列中等待。這樣,創建的線程就不會超過 corePoolSize。(因此,maximumPoolSize 的值也就無效了。)當每個任務完全獨立於其他任務,即任務執行互不影響時,適合於使用無界隊列.
(3) 有界隊列,當使用有限的 maximumPoolSizes 時,有界隊列(如 ArrayBlockingQueue)有助於防止資源耗盡,但是可能較難調整和控制。隊列大小和最大池大小可能需要相互折中:使用大型隊列和小型池可以最大限度地降低 CPU 使用率、操作系統資源和上下文切換開銷,但是可能導致人工降低吞吐量。如果任務頻繁阻塞(例如,如果它們是 I/O 邊界),則系統可能為超過您許可的更多線程安排時間。使用小型隊列通常要求較大的池大小,CPU 使用率較高,但是可能遇到不可接受的調度開銷,這樣也會降低吞吐量.

ThreadFactory:使用 ThreadFactory 創建新線程。如果沒有另外說明,則在同一個 ThreadGroup 中一律使用 Executors.defaultThreadFactory() 創建線程,並且這些線程具有相同的 NORM_PRIORITY 優先級和非守護進程狀態。通過提供不同的 ThreadFactory,可以改變線程的名稱、線程組、優先級、守護進程狀態等等。如果從 newThread 返回 null 時 ThreadFactory 未能創建線程,則執行程序將繼續運行,但不能執行任何任務。
在DefaultThreadFactory類中實現了ThreadFactory接口並對其中定義的方法進行了實現,如下:

    static class DefaultThreadFactory implements ThreadFactory {  
        private static final AtomicInteger poolNumber = new AtomicInteger(1);  
        private final ThreadGroup group;  
        private final AtomicInteger threadNumber = new AtomicInteger(1);  
        private final String namePrefix;  

        DefaultThreadFactory() {  
            SecurityManager s = System.getSecurityManager();  
            group = (s != null) ? s.getThreadGroup() :  Thread.currentThread().getThreadGroup();  
            namePrefix = "pool-" +  poolNumber.getAndIncrement() +  "-thread-";  
        }  
        // 為線程池創建新的任務執行線程  
        public Thread newThread(Runnable r) {  
            // 線程對應的任務是Runnable對象r  
            Thread t = new Thread(group, r,namePrefix + threadNumber.getAndIncrement(), 0);  
            // 設為非守護線程  
            if (t.isDaemon())  
                t.setDaemon(false);  
            // 將優先級設為Thread.NORM_PRIORITY  
            if (t.getPriority() != Thread.NORM_PRIORITY)  
                t.setPriority(Thread.NORM_PRIORITY);  
            return t;  
        }  
    }  

RejectedExecutionHandler:
當Executor已經關閉(即執行了executorService.shutdown()方法後),並且Executor將有限邊界用於最大線程和工作隊列容量,且已經飽和時,在方法execute()中提交的新任務將被拒絕.
  在以上述情況下,execute 方法將調用其 RejectedExecutionHandler 的 RejectedExecutionHandler.rejectedExecution(java.lang.Runnable, java.util.concurrent.ThreadPoolExecutor) 方法。下面提供了四種預定義的處理程序策略:

    1) 在默認的 ThreadPoolExecutor.AbortPolicy 處理程序遭到拒絕將拋出運行時 RejectedExecutionException;
    2) 在 ThreadPoolExecutor.CallerRunsPolicy 線程調用運行該任務的 execute 本身。此策略提供簡單的反饋控制機制,能夠減緩新任務的提交速度

    3) 在 ThreadPoolExecutor.DiscardPolicy 不能執行的任務將被刪除;

    4) 在 ThreadPoolExecutor.DiscardOldestPolicy 如果執行程序尚未關閉,則位於工作隊列頭部的任務將被刪除,然後重試執行程序(如果再次失敗,則重復此過程)。

線程池默認會采用的是defaultHandler策略。
Callable接口代表一段可以調用並返回結果的代碼;Future接口表示異步任務,是還沒有完成的任務給出的未來結果。所以說Callable用於產生結果,Future用於獲取結果。

以下內容來自http://www.trinea.cn/android/java-android-thread-pool/,再此簡單記錄.
new Thread的弊端:
a.每次new Thread新建對象性能差.
b.線程缺乏統一管理,可能無限制新建線程,相互之間競爭,及可能占用過多系統資源導致死機或oom.
c.缺乏更多功能,如定時執行、定期執行、線程中斷.
Java提供的四種線程池的好處:
a. 重用存在的線程,減少對象創建、消亡的開銷,性能佳。
b. 可有效控制最大並發線程數,提高系統資源的使用率,同時避免過多資源競爭,避免堵塞。
c. 提供定時執行、定期執行、單線程、並發數控制等功能。
(1). newCachedThreadPool
創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閒線程,若無可回收,則新建線程。線程池為無限大,當執行第二個任務時第一個任務已經完成,會復用執行第一個任務的線程,而不用每次新建線程。
(2). newFixedThreadPool
創建一個定長線程池,可控制線程最大並發數,超出的線程會在隊列中等待。定長線程池的大小最好根據系統資源進行設置。如Runtime.getRuntime().availableProcessors()。
(3) newScheduledThreadPool
創建一個定長線程池,支持定時及周期性任務執行。延遲執行示例代碼如下
(4)、newSingleThreadExecutor
創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。現行大多數GUI程序都是單線程的。Android中單線程可用於數據庫操作,文件操作,應用批量安裝,應用批量刪除等不適合並發但可能IO阻塞性及影響UI線程響應的操作。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved