Java多線程(十三):線程池

線程池類結構


1.Executor是頂級接口,有一個execute方法。
2.ExecutorService接口提供了管理線程的方法。
3.AbstractExecutorService管理普通線程,SchedulerExecutorService管理定時任務。java

簡單的示例dom

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());
    }
}

運行結果以下ide

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處理被拒絕的任務。code

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
示例代碼以下blog

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();
                    }
                }
            });
        }
    }
}

運行結果以下it

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自動回收空閒線程。
示例代碼以下io

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
相關文章
相關標籤/搜索