栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java线程池实现原理(java线程池面试题)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java线程池实现原理(java线程池面试题)

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

一:

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

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

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

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

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

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

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

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

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

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

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

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

    当不想提交任何任务时,调用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提供如下两个构造器:

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

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

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

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

    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个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/776611.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号