线程池有几种?分别有什么特点

Java通过Executors(jdk1.5并发包)提供四种线程池,分别为:

  1. newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  2. newFixedThreadPool创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  3. newScheduledThreadPool创建一个定长线程池,支持定时及周期性任务执行。
  4. newSingleThreadExecutor创建一个单线程化的线程池,它只会用唯一的工作线程来执行任
    务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

四种构建线程池的区别及特点:

  1. newCachedThreadPool
    特点:newCachedThreadPool创建一个可缓存线程池,如果当前线程池的长度超过了处理的需要时,它可以灵活的回收空闲的线程,当需要增加时,它可以灵活的添加新的线程,而不会对池的长度作任何限制
    缺点:它虽然可以无限的新建线程,但是容易造成堆外内存溢出,因为它的最大值是在初始化的时候设置为Integer.MAX_VALUE,一般来说机器都没那么大内存给它不断使用。当然知道可能出问题的点,就可以去重写一个方法限制一下这个最大值
    总结:线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程
    代码实列:
    package com.lijie;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class TestNewCachedThreadPool {
        public static void main(String[] args) {
            // 创建无限大小线程池,由jvm自动回收
            ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
            for (int i = 0; i < 10; i++) {
                final int temp = i;
                newCachedThreadPool.execute(new Runnable() {
                    public void run() {
                        try {
                            Thread.sleep(100);
                        } catch (Exception e) {
                    
                        }
                        System.out.println(Thread.currentThread().getName() + ",i==" + temp);
                    }
                 });
            }
        }
    }
    
  2. newFixedThreadPool
    特点:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。定长线程池的大小最好根据系统资源进行设置。
    缺点:线程数量是固定的,但是阻塞队列是无界队列。如果有很多请求积压,阻塞队列越来越长,容易导致OOM(超出内存空间)
    总结:请求的挤压一定要和分配的线程池大小匹配,定线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()
    代码实例:

    package com.lijie;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class TestNewFixedThreadPool {
        public static void main(String[] args) {
            ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(3);
            for (int i = 0; i < 10; i++) {
                final int temp = i;
                newFixedThreadPool.execute(new Runnable() {
                    public void run() {
                        System.out.println(Thread.currentThread().getName() + ",i==" + temp);
                    }
                });
            }
        }
    }

  3. newScheduledThreadPool
    特点:创建一个固定长度的线程池,而且支持定时的以及周期性的任务执行,类似于
    Timer(Timer是Java的一个定时器类)
    缺点:由于所有任务都是由同一个线程来调度,因此所有任务都是串行执行的,同一时间只能有一个任务在执行,前一个任务的延迟或异常都将会影响到之后的任务(比如:一个任务出错,以后的任务都无法继续)。
    代码示例:

    package com.lijie;
    
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    public class TestNewScheduledThreadPool {
        public static void main(String[] args) {
        //定义线程池大小为3
            ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(3);
            for (int i = 0; i < 10; i++) {
                final int temp = i;
                newScheduledThreadPool.schedule(new Runnable() {
                    public void run() {
                        System.out.println("i:" + temp);
                    }
                }, 3, TimeUnit.SECONDS);//这里表示延迟3秒执行。
            }
        }
    }

  4. newSingleThreadExecutor
    特点:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它,他必须保证前一项任务执行完毕才能执行后一项。保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
    缺点:缺点的话,很明显,他是单线程的,高并发业务下有点无力
    总结:保证所有任务按照指定顺序执行的,如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它
    代码实例:

    package com.lijie;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class TestNewSingleThreadExecutor {
        public static void main(String[] args) {
            ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
            for (int i = 0; i < 10; i++) {
                final int index = i;
                newSingleThreadExecutor.execute(new Runnable() {
                    public void run() {
                        System.out.println(Thread.currentThread().getName() + " index:" + index);
                        try {
                            Thread.sleep(200);
                        } catch (Exception e) {
    
                        }
                    }
                });
            }
        }
    }

你可能感兴趣的:(java,开发语言)