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
posted @ 2019-09-17 01:00  Rest探路者  阅读(677)  评论(0编辑  收藏  举报
levels of contents