Java自带线程池基本介绍

来源:互联网 发布:查看交换机端口ip 编辑:程序博客网 时间:2024/05/22 13:54

Java线程池

目前,Java提供了7个线程池给我们使用,各有各的特点。
1. newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
2. newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3. newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。
4. newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
5. newSingleThreadScheduledExcutor:创建一个单例线程池,定期或延时执行任务。
6. newWorkStealingPool:创建持有足够线程的线程池来支持给定的并行级别,并通过使用多个队列,减少竞争,它需要传一个并行级别的参数,如果不传,则被设定为默认的CPU数量。
7. ForkJoinPool:支持大任务分解成小任务的线程池,这是Java8新增线程池,通常配合ForkJoinTask接口的子类RecursiveAction或RecursiveTask使用。

newCachedThreadPool

newCachedThreadPool 会根据任务来临的需要决定是否创建新的线程,也就是如果来了新任务又没有空闲线程,它就会新建一个线程,下面用代码可以理解这个事情。

public static void main(String []ags) throws Exception{        ExecutorService service=Executors.newCachedThreadPool();        int count=10;        for(int i=0;i<count;++i){            final int temp=i;            service.execute(new Runnable() {                            @Override                public void run() {                    // TODO 自动生成的方法存根                    System.out.println("当前线程:"+Thread.currentThread()+" temp为:"+temp);                }            });            //不注释,只会产生一个线程,一直重用该线程。注释后有10个线程执行            Thread.sleep(1000);        }    }

不注释结果:
这里写图片描述

注释结果:(每次运行结果不一样)
这里写图片描述

newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

public static void main(String []ags) throws Exception{        ExecutorService service=Executors.newFixedThreadPool(3);        int count=10;        for(int i=0;i<count;++i){            final int temp=i;            service.execute(new Runnable() {                            @Override                public void run() {                    // TODO 自动生成的方法存根                    System.out.println("当前线程:"+Thread.currentThread()+" temp为:"+temp);                    try {                        Thread.sleep(1000);                    } catch (InterruptedException e) {                        // TODO 自动生成的 catch 块                        e.printStackTrace();                    }                }            });        }    }

每隔1秒输出3个线程信息:
这里写图片描述

newScheduledThreadPool

创建一个定长线程池,支持定时及周期性任务执行。

public static void main(String []ags) throws Exception{        ScheduledExecutorService service=Executors.newScheduledThreadPool(3);        int count=10;        for(int i=0;i<count;++i){            final int temp=i;            service.schedule(new Runnable() {                               @Override                public void run() {                    // TODO 自动生成的方法存根                    System.out.println("当前线程:"+Thread.currentThread()+" temp为:"+temp);                }            }, 2, TimeUnit.SECONDS);//延迟2秒后执行        }    }

这里写图片描述

public static void main(String []ags) throws Exception{        ScheduledExecutorService service=Executors.newScheduledThreadPool(3);        int count=10;        //for(int i=0;i<count;++i){            final int temp=count;            service.scheduleAtFixedRate(new Runnable() {                @Override                public void run() {                    // TODO 自动生成的方法存根                    System.out.println("当前线程:"+Thread.currentThread()+" temp为:"+temp);                }            }, 1, 3, TimeUnit.SECONDS);//初始延迟1秒后执行,之后每隔3秒执行一次    //  }    }

newSingleThreadExecutor

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

public static void main(String []ags) throws Exception{        ExecutorService service=Executors.newSingleThreadExecutor();        for(int i=0;i<10;++i){            final int temp=i;            //按顺序执行            service.execute(new Runnable() {                                @Override                public void run() {                    // TODO 自动生成的方法存根                    System.out.println("当前线程:"+Thread.currentThread()+" temp为:"+temp);                    try {                        Thread.sleep(1000);                    } catch (InterruptedException e) {                        // TODO 自动生成的 catch 块                        e.printStackTrace();                    }                }            });                 }       }

这里写图片描述

newWorkStealingPool

创建持有足够线程的线程池来支持给定的并行级别,并通过使用多个队列,减少竞争,它需要传一个并行级别的参数,如果不传,则被设定为默认的CPU数量。

public static void main(String []ags) throws Exception{        ExecutorService service=Executors.newWorkStealingPool();//默认CPU数量        for(int i=0;i<10;++i){            final int temp=i;            service.execute(new Runnable() {                                @Override                public void run() {                    // TODO 自动生成的方法存根                    System.out.println("当前线程:"+Thread.currentThread()+" temp为:"+temp);                    try {                        Thread.sleep(1000);                    } catch (InterruptedException e) {                        // TODO 自动生成的 catch 块                        e.printStackTrace();                    }                }            });                 }        Thread.sleep(100000);//不设置没有结果输出    }

这里写图片描述

ForkJoinPool

ForkJoinPool是一种支持任务分解的线程池,当提交给他的任务“过大”,他就会按照预先定义的规则将大任务分解成小任务,多线程并发执
行。

一般要配合可分解任务接口ForkJoinTask来使用,ForkJoinTask有两个实现它的抽象类:RecursiveAction和RecursiveTask,其区别是前者没有返回值,后者有返回值。

public static class Task extends RecursiveAction{        private static final long serialVersionUID = 1L;          //定义一个分解任务的阈值——10,即一个任务最多承担10个工作量          final static int TOP=10;          //任务量          int taskNum=0;         Task(int Num){              this.taskNum=Num;          }          @Override          protected void compute() {  //必须定义的方法,定义如何分解任务            if(taskNum<=TOP){                  System.out.println(Thread.currentThread()+"承担了"+taskNum+"份工作");                  try {                      Thread.sleep(1000);                  } catch (InterruptedException e) {                      e.printStackTrace();                  }              }else{                  //随机解成两个任务                  Random m=new Random();                  int x=m.nextInt(TOP);                  Task left=new Task(x);                  Task right=new Task(taskNum-x);                                    left.fork();                  right.fork();              }          }      }    public static void main(String []ags) throws Exception{        ForkJoinPool pool=new ForkJoinPool();//使用默认CPU数为最大线程数,使用默认线程Factory        pool.execute(new Task(50));        pool.awaitTermination(20, TimeUnit.SECONDS);//等待20s        pool.shutdown();    }

这里写图片描述

参看博客:
http://blog.csdn.net/a369414641/article/details/48350795
http://blog.csdn.net/a369414641/article/details/48342253
http://blog.csdn.net/u011479540/article/details/51867886