Androidスレッド切り替え、スレッドプール.


開発では、スレッド切り替えという機能を使用することがよくあります.最も一般的な使用シーンは、ネットワークリクエストやその他の時間のかかる処理が必要な場合、メインスレッドで呼び出すことはできません.そうしないと、スレッドが詰まりやすくなり、ANRがトリガーされやすいので、この場合、サブスレッドを新規作成して実行します.
        new Thread(new Runnable() {
            @Override
            public void run() {
                //         
                loadImage();
            }
        }).start();

しかし、この時問題がまた来て、画像のダウンロードが完了して、私たちがImageViewのために背景を設定したとき、また異常を投げ出しました.なぜですか.これは,Androidメカニズムでは非UIスレッドでのUI更新が許されず,一般的にはサブスレッドでのUI更新ができないためである.Androidは、プライマリ・スレッドで実行される方法を示しています.例:
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                image.setImageBitmap(bitmap);
            }
        });

もちろん、AndroidはHandlerクラスを提供しています.内部はスレッドプールに基づいており、より柔軟で便利で、公式にはHandlerを使用してUIを更新することをお勧めします.
        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
            image.setImageBitmap(bitmap);
            }
        });

これでAndroidのスレッド切り替えはこうなります.次に、このような弊害を見てみましょう.
new Thread     :
a.   new Thread       。
b.         ,         ,      ,                oom。
c.       ,     、    、    。  new Thread,Java             :
a.        ,      、     ,   。
b.             ,          ,          ,    。
c.       、    、   、        。

特定のシーンでは、スレッドプール:ExecutorServiceを使用する必要があります.
 Java  Executors       ,   : 
newCachedThreadPool          ,             ,         ,    ,     。 
newFixedThreadPool          ,          ,            。 
newScheduledThreadPool          ,            。 
newSingleThreadExecutor             ,                ,            (FIFO, LIFO,    )  。
        ExecutorService service= Executors.newCachedThreadPool();
        service.submit(new Runnable() {
            @Override
            public void run() {
                //         
                loadImage();
            }
        });

(1). 新CachedThreadPoolはキャッシュ可能なスレッドプールを作成し、スレッドプールの長さが処理の必要性を超えた場合、空きスレッドを柔軟に回収し、回収可能でない場合は新しいスレッドを作成します.サンプルコードは次のとおりです.
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();  
for (int i = 0; i < 10; i++) {  
    final int index = i;  
    try {  
        Thread.sleep(index * 1000);  
    } catch (InterruptedException e) {  
        e.printStackTrace();  
    }  

    cachedThreadPool.execute(new Runnable() {  

        @Override  
        public void run() {  
            System.out.println(index);  
        }  
    });  
} 

(2). 新FixedThreadPoolは、スレッドの最大同時数を制御し、超過したスレッドがキュー内で待機する定長スレッドプールを作成します.サンプルコードは次のとおりです.
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);  
for (int i = 0; i < 10; i++) {  
    final int index = i;  
    fixedThreadPool.execute(new Runnable() {  


        @Override  
        public void run() {  
            try {  
                System.out.println(index);  
                Thread.sleep(2000);  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
    });  
} 
        3,      index sleep 2 ,       3   。
                    。 Runtime.getRuntime().availableProcessors()。   PreloadDataCache。

(3)newScheduledThreadPoolは、タイミングおよび周期的なタスク実行をサポートする定長スレッドプールを作成します.遅延実行例コードは次のとおりです.
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);  
scheduledThreadPool.schedule(new Runnable() {  

    @Override  
    public void run() {  
        System.out.println("delay 3 seconds");  
    }  
}, 3, TimeUnit.SECONDS);  //    3   。

定期的に実行するサンプルコードは次のとおりです.
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {  

    @Override  
    public void run() {  
        System.out.println("delay 1 seconds, and excute every 3 seconds");  
    }  
}, 1, 3, TimeUnit.SECONDS); 
    1   3     。
ScheduledExecutorService Timer   ,     。

(4)、newSingleThreadExecutorは、指定された順序(FIFO、LIFO、優先度)ですべてのタスクが実行されるように、一意の作業スレッドでのみタスクを実行する単一スレッド化されたスレッドプールを作成します.サンプルコードは次のとおりです.
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();  
for (int i = 0; i < 10; i++) {  
    final int index = i;  
    singleThreadExecutor.execute(new Runnable() {  

        @Override  
        public void run() {  
            try {  
                System.out.println(index);  
                Thread.sleep(2000);  
            } catch (InterruptedException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
    });  
} 
      ,           。
     GUI        。Android            ,    ,      ,               IO      UI       。

ExecuterServiceのsubmit()とexecute()の違い
1.         submit()    runnable     callable     execute()  runnable     

2.submit    , execute  
    2.1        ,         validation task,      task   ,    task         ,       ,     ,     。

3.submit  Exception  
    3.1          task    checked  unchecked exception,                 exception        ,       submit,    Future.get     。

shotdown()showdown Now()の違い
     ExecutorService,          。          ExecutorService。 shutdown()                  , shutdownNow()                        。               ,          ,         。       ExecutorService         。           ExecutorService。       shutdown      ,     shutdownNow(    )         
//         ,         ,       。
    threadPool.shutdown();