查看原文
其他

JDK1.8 创建线程池有哪几种方式?

点击关注👉 一行Java 2022-08-09


JDK1.8 创建线程池有哪几种方式?

  • newFixedThreadPool

    定长线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程数量不再变化,当线程发生错误结束时,线程池会补充一个新的线程

    测试代码:

    public class TestThreadPool {
     
     //定长线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程数量不再变化,当线程发生错误结束时,线程池会补充一个新的线程
     static ExecutorService fixedExecutor = Executors.newFixedThreadPool(3);
     
     
     public static void main(String[] args) {
      testFixedExecutor();
     }
     
     //测试定长线程池,线程池的容量为3,提交6个任务,根据打印结果可以看出先执行前3个任务,3个任务结束后再执行后面的任务
     private static void testFixedExecutor() {
      for (int i = 0; i < 6; i++) {
       final int index = i;
       fixedExecutor.execute(new Runnable() {
        public void run() {
         try {
          Thread.sleep(3000);
         } catch (InterruptedException e) {
          e.printStackTrace();
         }
         System.out.println(Thread.currentThread().getName() + " index:" + index);
        }
       });
      }
      
      try {
       Thread.sleep(4000);
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
      System.out.println("4秒后...");
      
      fixedExecutor.shutdown();
     }
     
    }

    打印结果:

    pool-1-thread-1 index:0

    pool-1-thread-2 index:1

    pool-1-thread-3 index:2

    4秒后...

    pool-1-thread-3 index:5

    pool-1-thread-1 index:3

    pool-1-thread-2 index:4

  • newCachedThreadPool

    可缓存的线程池,如果线程池的容量超过了任务数,自动回收空闲线程,任务增加时可以自动添加新线程,线程池的容量不限制

    测试代码:

    public class TestThreadPool {
     
     //可缓存的线程池,如果线程池的容量超过了任务数,自动回收空闲线程,任务增加时可以自动添加新线程,线程池的容量不限制
     static ExecutorService cachedExecutor = Executors.newCachedThreadPool();
     
     
     public static void main(String[] args) {
      testCachedExecutor();
     }
     
     //测试可缓存线程池
     private static void testCachedExecutor() {
      for (int i = 0; i < 6; i++) {
       final int index = i;
       cachedExecutor.execute(new Runnable() {
        public void run() {
         try {
          Thread.sleep(3000);
         } catch (InterruptedException e) {
          e.printStackTrace();
         }
         System.out.println(Thread.currentThread().getName() + " index:" + index);
        }
       });
      }
      
      try {
       Thread.sleep(4000);
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
      System.out.println("4秒后...");
      
      cachedExecutor.shutdown();
     }
     
    }

    打印结果:

    pool-1-thread-1 index:0

    pool-1-thread-6 index:5

    pool-1-thread-5 index:4

    pool-1-thread-4 index:3

    pool-1-thread-3 index:2

    pool-1-thread-2 index:1

    4秒后...

  • newScheduledThreadPool 定长线程池,可执行周期性的任务

    测试代码:

    public class TestThreadPool {
     
     //定长线程池,可执行周期性的任务
     static ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(3);
     
     
     public static void main(String[] args) {
      testScheduledExecutor();
     }
     
     //测试定长、可周期执行的线程池
     private static void testScheduledExecutor() {
      for (int i = 0; i < 3; i++) {
       final int index = i;
       //scheduleWithFixedDelay 固定的延迟时间执行任务;scheduleAtFixedRate 固定的频率执行任务
       scheduledExecutor.scheduleWithFixedDelay(new Runnable() {
        public void run() {
         System.out.println(Thread.currentThread().getName() + " index:" + index);
        }
       }, 03, TimeUnit.SECONDS);
      }
      
      try {
       Thread.sleep(4000);
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
      System.out.println("4秒后...");
      
      scheduledExecutor.shutdown();
     }
     
    }

    打印结果:

    pool-1-thread-1 index:0

    pool-1-thread-2 index:1

    pool-1-thread-3 index:2

    pool-1-thread-1 index:0

    pool-1-thread-3 index:1

    pool-1-thread-1 index:2

    4秒后...

  • newSingleThreadExecutor

    单线程的线程池,线程异常结束,会创建一个新的线程,能确保任务按提交顺序执行

    测试代码:

    public class TestThreadPool {
     
     //单线程的线程池,线程异常结束,会创建一个新的线程,能确保任务按提交顺序执行
     static ExecutorService singleExecutor = Executors.newSingleThreadExecutor();
     
     
     public static void main(String[] args) {
      testSingleExecutor();
     }
     
     //测试单线程的线程池
     private static void testSingleExecutor() {
      for (int i = 0; i < 3; i++) {
       final int index = i;
       singleExecutor.execute(new Runnable() {
        public void run() {
         try {
          Thread.sleep(3000);
         } catch (InterruptedException e) {
          e.printStackTrace();
         }
         System.out.println(Thread.currentThread().getName() + " index:" + index);
        }
       });
      }
      
      try {
       Thread.sleep(4000);
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
      System.out.println("4秒后...");
      
      singleExecutor.shutdown();
     }
     
    }

    打印结果:

    pool-1-thread-1 index:0

    4秒后...

    pool-1-thread-1 index:1

    pool-1-thread-1 index:2

  • newSingleThreadScheduledExecutor

    单线程可执行周期性任务的线程池

    测试代码:

    public class TestThreadPool {
     
     //单线程可执行周期性任务的线程池
     static ScheduledExecutorService singleScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
     
     
     public static void main(String[] args) {
      testSingleScheduledExecutor();
     }
     
     //测试单线程可周期执行的线程池
     private static void testSingleScheduledExecutor() {
      for (int i = 0; i < 3; i++) {
       final int index = i;
       //scheduleWithFixedDelay 固定的延迟时间执行任务;scheduleAtFixedRate 固定的频率执行任务
       singleScheduledExecutor.scheduleAtFixedRate(new Runnable() {
        public void run() {
         System.out.println(Thread.currentThread().getName() + " index:" + index);
        }
       }, 03, TimeUnit.SECONDS);
      }
      
      try {
       Thread.sleep(4000);
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
      System.out.println("4秒后...");
      
      singleScheduledExecutor.shutdown();
     }
     
    }

    打印结果:

    pool-1-thread-1 index:0

    pool-1-thread-1 index:1

    pool-1-thread-1 index:2

    pool-1-thread-1 index:0

    pool-1-thread-1 index:1

    pool-1-thread-1 index:2

    4秒后...

  • newWorkStealingPool

    任务窃取线程池,不保证执行顺序,适合任务耗时差异较大。

    线程池中有多个线程队列,有的线程队列中有大量的比较耗时的任务堆积,而有的线程队列却是空的,就存在有的线程处于饥饿状态,当一个线程处于饥饿状态时,它就会去其它的线程队列中窃取任务。解决饥饿导致的效率问题。

    默认创建的并行 level 是 CPU 的核数。主线程结束,即使线程池有任务也会立即停止。

    测试代码:

    public class TestThreadPool {
     
     //任务窃取线程池
     static ExecutorService workStealingExecutor = Executors.newWorkStealingPool();
     
     public static void main(String[] args) {
      testWorkStealingExecutor();
     }
     
     //测试任务窃取线程池
     private static void testWorkStealingExecutor() {
      for (int i = 0; i < 10; i++) {//本机 CPU 8核,这里创建10个任务进行测试
       final int index = i;
       workStealingExecutor.execute(new Runnable() {
        public void run() {
         try {
          Thread.sleep(3000);
         } catch (InterruptedException e) {
          e.printStackTrace();
         }
         System.out.println(Thread.currentThread().getName() + " index:" + index);
        }
       });
      }
      
      try {
       Thread.sleep(4000);//这里主线程不休眠,不会有打印输出
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
      System.out.println("4秒后...");
      
    //  workStealingExecutor.shutdown();
     }
     
    }

    打印结果如下,index:8,index:9并未打印出:

    ForkJoinPool-1-worker-1 index:0

    ForkJoinPool-1-worker-7 index:6

    ForkJoinPool-1-worker-5 index:4

    ForkJoinPool-1-worker-3 index:2

    ForkJoinPool-1-worker-4 index:3

    ForkJoinPool-1-worker-2 index:1

    ForkJoinPool-1-worker-0 index:7

    ForkJoinPool-1-worker-6 index:5

    4秒后...

来源:blog.csdn.net/meism5/article/details/90261021

END

精品资料,超赞福利,免费领


点击👇名片,关注公众号,回复【  资料  
获取大厂面试资料2T+视频教程10G+电子书
各类精品资料。

注:资料太多,截图为其中部分

最近开发整理了一个用于速刷面试题的小程序;其中收录了上千道常见面试题及答案(包含基础、并发、JVM、MySQL、Redis、Spring、SpringMVC、SpringBoot、SpringCloud、消息队列等多个类型),欢迎您的使用。QQ交流群:912509560


别再用SVN了, 图解 GIT,带你入门到精通
Web 登录实现很简单?开什么玩笑!
IDEA 那些既好用又好玩的宝贝插件,你知道多少?
List复制:深拷贝和浅拷贝用法及区别
延时队列的几种实现姿势?日常必备技能!
MySQL 批量插入:如何不插入重复数据?
别再花精力封装各种Util工具类了,这款神级框架都有

👇👇
👇点击"阅读原文",获取更多资料(持续更新中)

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存