1. 程式人生 > >java執行緒之Executor框架與執行緒池

java執行緒之Executor框架與執行緒池

執行緒雖然在web開發中用的不算特別多,但在特定的情況下還是能發揮重要重要作用的,因此即使用的少還是掌握下比較好;下面先回顧下比較執行緒的常規實現方法

1 繼承Thread類

2 實現runnable介面(使用較多)

java5之後有了新的執行緒實現方式,java5可以使用Executor來啟動執行緒,效率更好;這次主要從Executor執行runnable任務、callable任務、自定義執行緒池三個方面進行學習分享

一  Executor執行runnable任務、callable任務

callable任務相比runnable任務的區別在於它有返回值,每個任務執行後可以通過Future返回結果

1 Executor執行runnable任務(列印執行的任務和負責執行的執行緒名稱)

package com.debug;

import java.util.concurrent.*;

public class Executor01 {
       public static void main(String aargs[]){
                     //ExecutorService pool=Executors.newFixedThreadPool(5);固定數目執行緒池
                     //ExecutorService pool=Executors.newSingleThreadExecutor();單例執行緒池
                     ExecutorService executorService=Executors.newCachedThreadPool();//快取型池子

                     for (int i = 1; i <= 5; i++){
                           executorService.execute(new Executor01Runnable(i));

                     }
                    executorService.shutdown();

       }

}
class Executor01Runnable implements Runnable{
    private int task;
    public Executor01Runnable(int task){
        this.task=task;
    }
   public void run(){
       System.out.println("第"+task+"個任務被"+Thread.currentThread().getName() + "執行緒執行了");
   }
}


執行的結果截圖如下所示:



2 Executor執行callable任務

runnable任務執行使用execute方法,但callable使用submit;

submit 也是首先選擇空閒執行緒來執行任務,如果沒有,才會建立新的執行緒來執行任務。另外,需要注意:如果Future的返回尚未完成,則get()方法會阻塞等待,直到Future完成返回,可以通過呼叫isDone()方法判斷Future是否完成了返回。

package com.debug;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;

public class UseCallable {
    public static void main(String aargs[]){
        ExecutorService pool=Executors.newCachedThreadPool();
        List<Future<String>> arr=new ArrayList<Future<String>>();
        for(int i=1;i<=10;i++){
            Future<String> res=pool.submit(new ThreadTaskWithResult(i));
            arr.add(res);


        }
        Iterator<Future<String>> it=arr.iterator();
        while(it.hasNext()){
            Future<String> result=it.next();

            try {
                System.out.println(result.get());
                //System.out.println(result.get());

            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            } finally {
                pool.shutdown();
            }

        }
        // pool.shutdown();
    }

}

class ThreadTaskWithResult implements Callable<String> {
    private int count;
    public ThreadTaskWithResult(int count){
        this.count=count;
    }
    public String call() throws Exception {
        System.out.println("call()方法被自動呼叫!!!    " + Thread.currentThread().getName());
        return "第"+count+"個任務執行完畢,執行任務的執行緒是:"+Thread.currentThread().getName();
    }
}

執行的結果截圖如下所示:


二  自定義執行緒池

package com.debug;

import java.util.concurrent.*;

public class CustomThreadPool {

    public static void main(String args[]) throws Exception{
        //建立等待佇列
        BlockingQueue<Runnable> block=new ArrayBlockingQueue<Runnable>(30);
        //建立執行緒池,最小3個,最大10個
        ThreadPoolExecutor pool=new ThreadPoolExecutor(3,5,1000, TimeUnit.MILLISECONDS,block);

        pool.execute(new CustomRunnable());
        pool.execute(new CustomRunnable());
        pool.execute(new CustomRunnable());
        pool.execute(new SpecilCustomRunnable());
        pool.execute(new SpecilCustomRunnable());

        pool.shutdown();

    }
}
class CustomRunnable implements Runnable{
    public void run(){
        System.out.println("CustomRunnable  "+Thread.currentThread().getName() + "執行緒被呼叫了。");
    }
}
class SpecilCustomRunnable implements Runnable{
    public void run(){
        System.out.println("SpecilCustomRunnable  "+Thread.currentThread().getName() + "執行緒被呼叫了。");
        for(int i=1;i<5;i++){
            System.out.println("SpecilCustomRunnable  "+Thread.currentThread().getName() + "迴圈執行到第"+i+"次");
        }

    }
}

文章可能寫的潦草,只能算自己的隨筆和摘抄,大部分靈感都來源於下面這篇部落格,可以順帶看一看