写点什么

【线程】,东软集团 Java 笔试题

用户头像
极客good
关注
发布于: 刚刚

// });


//执行线程池方法二


// threadpool.submit(new Runnable() {


// @Override


// public void run() {


// System.out.println("线程池的名称"+Thread.currentThread().getName());


// }


// });


//执行线程池方法三


threadpool.execute(()->{


System.out.println("线程池的名称"+Thread.currentThread().getName());


});


}


}


}


执行结果





方式二:创建一个可缓存的线程池


代码案例


import java.util.concurrent.ExecutorService;


import java.util.concurrent.Executors;


/**


  • 创建一个可缓存的线程池,若线程数超过处理所需,

  • 缓存一段时间后会回收,若线程数不够,则新建一个线程


*/


public class ThreadDemo20 {


public static void main(String[] args) {


ExecutorService threadpool = Executors.newCachedThreadPool();


//这里要注意,你有几个任务他就会创建几个线程来执行任务,即便你的电脑是八核,但是还是会创建出 5 个线程


// 所以这也是使用这种线程池的风险


for (int i = 0; i < 5; i++) {


threadpool.submit(() -> {


System.out.println("线程名称:"+ Thread.currentThread().getName());


});


}


}


}


执行结果



方式三:创建单个线程数的线程池,但是能够保证执行顺序


代码案例


/**


  • 创建单个线程的线程池,但是能够保证线程的执行顺序


*/


import java.util.concurrent.ExecutorService;


import java.util.concurrent.Executors;


public class ThreadDemo21 {


public static void main(String[] args) {


ExecutorService threadpool = Executors.newSingleThreadExecutor();


//有 10 个任务,但是只有一个线程执行,并且是按照顺序执行的


for (int i = 0; i < 10; i++) {


threadpool.submit(()->{


System.out.println("线程名称"+Thread.currentThread().getName());


});


}


}


}


执行结果



单个线程池的优点


1.避免重复的创建和销毁线程


2.单个线程池里面也有任务队列,可以用来存储很多的任务




方式四:创建一个单线程可以执行延迟任务的线程池


代码案例


/**


  • 创建一个单线程可以执行延迟任务的线程池

  • 注意:这里的返回值类型和调用方法和前面的不太一样


*/


public class ThreadDemo22 {


public static void main(String[] args) {


//创建单个可以延迟任务的线程池


ScheduledExecutorService threadpool = Executors.newSingleThreadScheduledExecutor();


System.out.println("添加任务的时间:"+new Date());


threadpool.schedule(()->{


System.out.println("执行任务的时间:"+new Date());


},5,TimeUnit.SECONDS);


}


}


执行结果





方式五:创建多个可以执行延迟任务的线程池


代码案例


/**


  • 创建可以执行多个延迟任务的线程池

  • 注意返回值以及调用方法


*/


public class ThreadDemo23 {


public static void main(String[] args) {


ScheduledExecutorService threadpool = Executors.newScheduledThreadPool(5);


for (int i = 0; i < 6; i++) {


System.out.println("添加任务的时间"+new Date());


threadpool.schedule(()->{


System.out.println("执行任务的时间"+new Date());


},5,TimeUnit.SECONDS);


}


}


}


执行结果



方式六:创建一个抢占式执行的线程池,执行任务的顺序不确定


代码案例


import java.util.concurrent.ExecutorService;


import java.util.concurrent.Executors;


/**


  • 创建一个抢占式执行的线程池

  • 执行任务的顺序不确定


*/


public class ThreadDemo24 {


public static void main(String[] args) {


//创建线程池


ExecutorService threadpool = Executors.newWorkStealingPool();


for (int i = 0; i < 5; i++) {


int index = i;


threadpool.submit(()->{


System.out.println("任务 "+index+" 正在被线程名称为 "+Thread.currentThread().getName()+"执行");


});


}


//确保任务执行完成


while (!threadpool.isTerminated()) {


}


}


}


执行结果



方式七:是最原始的一种,也是最重要的一种,使用 ThreadPoolExcutors 创建线程池,里面至少传五个参数


7.1 参数的介绍



1.corPoolSize 核心线程数,线程池中始终存活的线程数


2.mamaximumPoolSize 线程池所能容纳的最大线程数,当线程池的任务队列满了之后可以创建的最大线程数


3.keepAliveTime 最大线程数可以存活的时间,如果超过该时长,非核心线程就会被回收,也就是当线程中没有任务执行时,最大线程就会销毁一部分,最终保持核心线程数量的线程。


4.指定 keepAliveTime 参数的时间单位。常用的有:TimeUnit.MILLISECONDS(毫秒)、TimeUnit.SECONDS(秒)、TimeUnit.MINUTES(分)


5.一个阻塞队列,用来存储线程池等待执行的任务,均为线程安全


6.threadFactory:线程工厂。用于指定为线程池创建新线程的方式。


7.handler: 拒绝处理任务时的策略——拒绝策略有五种,如:


  • AbortPolicy:拒绝并抛出异常。

  • CallerRunsPolicy:使用当前调用的线程来执行此任务。

  • DiscardOldestPolicy:抛弃队列头部(最旧)的一个任务,并执行当前任务。

  • DiscardPolicy:忽略并抛弃当前任务。

  • 程序员自己定义的拒绝策略


ThreadPoolExecutors 的执行执行逻辑


1.当任务量较少的时候使用线程池提供的核心线程数执行执行


2.当任务超过核心线程数的时候,新来的任务就会存储到队列


3.当队列已经存储满的了,那么就会增加线程的数量,一直增加到可以扩展的最大线程数,也就是 mamaximumPoolSize


4.当最大线程数已满,任务队列已满,就会执行线程池的拒绝策略(5 钟拒绝策略)



注意



[](


)拒绝策略(ThreadPoolExecutors)




JDK(4 钟拒绝策略)


  • 拒绝执行新来任务,并抛出异常(默认拒绝策略)

  • 可以使用主线程来执行新任务(main 主线程)

  • 忽略当前任务,但不报错

  • 忽略旧的任务,也不报错


程序员自己定义的拒绝策略


拒绝策略一 :拒绝执行新来任务,并抛出异常


import java.util.concurrent.LinkedBlockingQueue;


import java.util.concurrent.ThreadPoolExecutor;


import java.util.concurrent.TimeUnit;


public class ThreadDemo25 {


public static void main(String[] args) {


//最大线程数一定要大于等于核心线程数,不然就会报错


ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2, 5, 100, Tim


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


eUnit.SECONDS,


new LinkedBlockingQueue<>(2), new ThreadPoolExecutor.AbortPolicy());


for (int i = 0; i < 10; i++) {


final int index = i;


threadPoolExecutor.submit(() -> {


System.out.println("我是任务 "+ index);


});


}


}


}


执行结果





用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
【线程】,东软集团Java笔试题