1. 程式人生 > >Java多執行緒(十三):執行緒池

Java多執行緒(十三):執行緒池

執行緒池類結構


1.Executor是頂級介面,有一個execute方法。
2.ExecutorService介面提供了管理執行緒的方法。
3.AbstractExecutorService管理普通執行緒,SchedulerExecutorService管理定時任務。

簡單的示例

public class MyThread46 {
    public static void main(String[] args)
    {
        long startTime = System.currentTimeMillis();
        final List<Integer> l = new LinkedList<Integer>();
        ThreadPoolExecutor tp = new ThreadPoolExecutor(100, 100, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(20000));
        final Random random = new Random();
        for (int i = 0; i < 20000; i++)
        {
            tp.execute(new Runnable()
            {
                public void run()
                {
                    l.add(random.nextInt());
                }
            });
        }
        tp.shutdown();
        try
        {
            tp.awaitTermination(1, TimeUnit.DAYS);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        System.out.println(System.currentTimeMillis() - startTime);
        System.out.println(l.size());
    }
}

執行結果如下

52
19919

ThreadPoolExecutor七個引數

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)

1.corePoolSize
執行緒池當前可以存在的執行緒數量
2.maximumPoolSize
執行緒池允許的最大執行緒數量
3.keepAliveTime
當執行緒數量比corePoolSize大時才會起作用,終止前的空餘執行緒等待的最長時間。
4.unit
keepAliveTime的時間單位
5.workQueue
儲存未被執行的任務
6.threadFactory
executor建立新執行緒時使用的工廠
7.handler
當執行被阻塞時使用handler

corePoolSize與maximumPoolSize的關係

1.池中執行緒數小於corePoolSize,新任務都不排隊而是直接新增新執行緒。

2.池中執行緒數大於等於corePoolSize,workQueue未滿,將新任務加入workQueue而不是新增新執行緒。
3.池中執行緒數大於等於corePoolSize,workQueue已滿,但是執行緒數小於maximumPoolSize,新增新的執行緒來處理被新增的任務。
4.池中執行緒數大於等於corePoolSize,workQueue已滿,並且執行緒數大於等於maximumPoolSize,新任務被拒絕,使用handler處理被拒絕的任務。

Executors

1.newSingleThreadExecutos() 單執行緒執行緒池

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

來新任務就排隊,workQueue採用了無界佇列LinkedBlockingQueue
示例程式碼如下

public class MyThread47{
    static ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

    public static void main(String[] args) {
        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(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        }

}

執行結果如下

0
1
2
3
4
5
6
7
8
9

2.newFixedThreadPool(int nThreads) 固定大小執行緒池

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

固定大小執行緒池和單執行緒執行緒池類似,可以手動指定執行緒數量
示例程式碼如下

public class MyThread48 {
    public static void main(String[] args) {
        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(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}

執行結果如下

0
1
2
3
4
5
6
8
7
9

3.newCachedThreadPool() 無界執行緒池

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

有多少任務來直接執行,執行緒池最大數量Integer.MAX_VALUE,60s自動回收空閒執行緒。
示例程式碼如下

public class MyThread49 {
    public static void main(String[] args) {
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            cachedThreadPool.execute(new Runnable() {

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

執行結果如下

0
1
2
3
4
5
6
7
8
9