Java线程池

背景:Java5开始,Java内建支持线程池。

一:

通过Executors工厂类来创建线程池包含如下方法

  1. newCachedThreadPool( ):创建一个具有缓存功能的线程池;

  2. newFixedThreadExecutor( ):创建一个只有单线程的线程池;

  3. newSingleThreadExecutor( ):创建一个只有单线程的线程池

  4. newScheduledThreadPool(int corePoolSize):创建具有指定线程数的线程池

  5. newSingleThreadScheduledExecutor( ):创建只有一个线程的线程池。

  6. ExecutorService newWorkStealingPool(int parallelism):创建持有足够的线程的线程池来支持给定的并行级别,该方法还会使用多个队列来减少竞争。

  7. ExecutorService newWorkStealingPool( ):该方法是前一个方法的简化版本。如果机器有4个CPU,则目标并行级别被设置为4。

使用线程池来执行线程任务的步骤如下

  1. 调用Executors类的静态工厂方法创建一个ExecutorService对象,该对象代表一个线程

  2. 创建Runnable实现类或Callable实现类的实例,作为线程执行任务

  3. 调用ExecutorService对象的submit()方法来提交Runnable实例或Callable实例

  4. 当不想提交任何任务时,调用ExecutorService对象的shutdown( )方法来关闭线程池。

具体执行方式:

//创建一个具有固定线程数的线程池

ExecutorService pool = Executors.newFixedThreadPool(6);

//使用Lambda表达式创建Runnable对象

Runnable target =()->{

for(var i=0;i<100;i++) {

    System.out.println(Thread.currentThread().getName()+"的i值为"+i);

   }

};

 //向线程池中提交两个线程

 pool.submit(target);

 pool.submit(target);

 //关闭线程池

 pool.shutdown();

二:

使用ForkJoinPool利用多CPU(将一个任务拆分成多个小任务放到多个处理器核心上并行执行,再将所有任务的执行结果合并)

ForkJoinPool是ExecutorService的实现类。是一种特殊的线程池

ForkJoinPool提供如下两个构造器:

  1. ForkJoinPool(int a):创建一个包含a个并行线程的ForkJoinPool

  2. ForkJoinPool():以Runtime.availableProcessors( )方法的返回值作为a参来来创建ForkJoinPool

ForkJoinPool类通过如下两个方法提供通用池功能

  1. ForkJoinPool commonPool( ):该方法返回一个通用池,通用池的运行状态不会受shutdown( )或shutdownNow( )方法的影响。可以直接执行System.exit(0)终止正在执行的任务

  2. int getCommonPoolParallelism( ):该方法返回通用池的并行级别。

创建ForkJoinPool实例之后,调用ForkJoinPool的submit(ForkJoinTask task)或invoke(ForkJoinTask task)方法来执行指定任务。ForkJoinTask代表一个可以并行,合并的任务

注:ForkJoinTask是一个抽象类,它有两个抽象子类:RecursiveAction和RecursiveTask。前者代表没有返回值的任务,后者代表有返回值的任务。

                   // 将大任务分解成两个小任务。

                    int middle = (start + end) / 2;

                    var left = new PrintTask(start, middle);

                    var right = new PrintTask(middle, end);

                    // 并行执行两个“小任务”

                    left.fork();

                    right.fork();

            var pool = new ForkJoinPool();

             // 提交可分解的PrintTask任务

             pool.submit(new PrintTask(0, 300));

             pool.awaitTermination(2, TimeUnit.SECONDS);

             // 关闭线程池

             pool.shutdown();

遗忘点:

awaitTermination(2, TimeUnit.SECONDS);

2指的是等待关闭线程执行器的时间大小,第一个时间参数的单位

注: fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值