Java最新Java多线程一次给你整明白,详细解说

最后

分享一套我整理的面试干货,这份文档结合了我多年的面试官经验,站在面试官的角度来告诉你,面试官提的那些问题他最想听到你给他的回答是什么,分享出来帮助那些对前途感到迷茫的朋友。

面试经验技巧篇
  • 经验技巧1 如何巧妙地回答面试官的问题
  • 经验技巧2 如何回答技术性的问题
  • 经验技巧3 如何回答非技术性问题
  • 经验技巧4 如何回答快速估算类问题
  • 经验技巧5 如何回答算法设计问题
  • 经验技巧6 如何回答系统设计题
  • 经验技巧7 如何解决求职中的时间冲突问题
  • 经验技巧8 如果面试问题曾经遇见过,是否要告知面试官
  • 经验技巧9 在被企业拒绝后是否可以再申请
  • 经验技巧10 如何应对自己不会回答的问题
  • 经验技巧11 如何应对面试官的“激将法”语言
  • 经验技巧12 如何处理与面试官持不同观点这个问题
  • 经验技巧13 什么是职场暗语

面试真题篇
  • 真题详解1 某知名互联网下载服务提供商软件工程师笔试题
  • 真题详解2 某知名社交平台软件工程师笔试题
  • 真题详解3 某知名安全软件服务提供商软件工程师笔试题
  • 真题详解4 某知名互联网金融企业软件工程师笔试题
  • 真题详解5 某知名搜索引擎提供商软件工程师笔试题
  • 真题详解6 某初创公司软件工程师笔试题
  • 真题详解7 某知名游戏软件开发公司软件工程师笔试题
  • 真题详解8 某知名电子商务公司软件工程师笔试题
  • 真题详解9 某顶级生活消费类网站软件工程师笔试题
  • 真题详解10 某知名门户网站软件工程师笔试题
  • 真题详解11 某知名互联网金融企业软件工程师笔试题
  • 真题详解12 国内某知名网络设备提供商软件工程师笔试题
  • 真题详解13 国内某顶级手机制造商软件工程师笔试题
  • 真题详解14 某顶级大数据综合服务提供商软件工程师笔试题
  • 真题详解15 某著名社交类上市公司软件工程师笔试题
  • 真题详解16 某知名互联网公司软件工程师笔试题
  • 真题详解17 某知名网络安全公司校园招聘技术类笔试题
  • 真题详解18 某知名互联网游戏公司校园招聘运维开发岗笔试题

资料整理不易,点个关注再走吧

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

复制代码

1 /**

2 * @description: 多线程实现方法2:实现Runnable接口

3 **/

4 @Slf4j

5 public class MyThread2 implements Runnable {

6 ​

7 @Override

8 public void run() {

9 log.info(“MyThread1”);

10 log.info(“MyThread2”);

11 }

12 ​

13 public static void main(String[] args) {

14 MyThread2 m = new MyThread2();

15 //1.调用run方法

16 Thread t1 = new Thread(m);

17 Thread t2 = new Thread(m);

18 t1.start();

19 t2.start();

20 }

21 }

复制代码

2.3实现 Callable 接口,通过 Future Task 包装器来创建 Thread 线程


可以获取线程的返回值

复制代码

1 /**

2 * @description: 多线程实现方法2:实现Callable接口

3 * @author: DZ

4 **/

5 @Slf4j

6 public class MyThread3 implements Callable {

7 @Override

8 public String call() throws Exception {

9 log.info(“MyThread1”);

10 log.info(“MyThread2”);

11 return “MyThread3”;

12 }

13 ​

14 public static void main(String[] args) throws ExecutionException, InterruptedException {

15 MyThread3 m = new MyThread3();

16 //存储返回值,其中泛型为返回值的类型

17 FutureTask futureTask = new FutureTask<>(m);

18 new Thread(futureTask).start();

19 System.out.println(futureTask.get());

20 }

21 ​

22 }

复制代码

2.4通过线程池


2.4.1 线程池的主要参数

1 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue) {

2 this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,

3 Executors.defaultThreadFactory(), defaultHandler);

4 }

  • corePoolSize

当向线程池提交一个任务时,若线程池已创建的线程数小于corePoolSize,即便此时存在空闲线程,也会通过创建一个新线程来执行该任务,直到已创建的线程数大于或等于corePoolSize时,(除了利用提交新任务来创建和启动线程(按需构造),也可以通过 prestartCoreThread() 或 prestartAllCoreThreads() 方法来提前启动线程池中的基本线程。)

  • maximumPoolSize

线程池所允许的最大线程个数。当队列满了,且已创建的线程数小于maximumPoolSize,则线程池会创建新的线程来执行任务。另外,对于无界队列,可忽略该参数

  • keepAliveTime

当线程池中线程数大于核心线程数时,线程的空闲时间如果超过线程存活时间,那么这个线程就会被销毁,直到线程池中的线程数小于等于核心线程数

  • workQueue

用于传输和保存等待执行任务的阻塞队列

  • ArrayBlockingQueue:一个由数组结构组成的有界阻塞队列

  • LinkedBlockingQueue 一个由链表结构组成的有界阻塞队列

  • PriorityBlockingQueue 一个支持优先级排序的无界阻塞队列

  • DelayQueue 一个使用优先级队列实现的无界阻塞队列

  • SynchronousQueue 一个不存储元素的阻塞队列

  • LinkedTransferQueue 一个由链表结构组成的无界阻塞队列

  • LinkedBlockingDeque 一个由链表结构组成的双向阻塞队列

**作用:**阻塞队列可以保证任务队列中没有任务时阻塞获取任务的线程,使得线程进入wait状态,释放cpu资源。当队列中有任务时才唤醒对应线程从队列中取出消息进行执行。使得在线程不至于一直占用cpu资源。

  • threadFactory

用于创建新线程。threadFactory创建的线程也是采用new Thread()方式,threadFactory创建的线程名都具有统一的风格:pool-m-thread-n(m为线程池的编号,n为线程池内的线程编号)

  • handler

当线程池和队列都满了,再加入线程会执行此策略

AbortPolicy: 直接抛出异常,阻止线程正常运行

1 public static class AbortPolicy implements RejectedExecutionHandler {

2 public AbortPolicy() {}

3 public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {

4 throw new RejectedExecutionException(“Task " + r.toString() +” rejected from " + e.toString());

5 }

6 }

CallerRunsPolicy: 直接在方法的调用线程中执行,除非线程池已关闭

复制代码

1 public static class CallerRunsPolicy implements RejectedExecutionHandler {

2 public CallerRunsPolicy() {}

3 public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {

4 if (!e.isShutdown()) {

5 r.run();

6 }

7 }

8 }

复制代码

DiscardPolica: 丢弃当前的线程任务而不做任何处理。如果系统允许在资源不足的情况下弃部分任务,则这将是保障系统安全、稳定的一种很好的方案

1 public static class DiscardPolicy implements RejectedExecutionHandler {

2 public DiscardPolicy() {}

3 public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {

4 }

5 }

DiscardOlderPolicy: 移除线程队列中最早(老)的一个线程任务,并尝试提交当前任务

复制代码

1 public static class DiscardOldestPolicy implements RejectedExecutionHandler {

2 public DiscardOldestPolicy() { }

3 public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {

4 if (!e.isShutdown()) {

5 e.getQueue().poll();// 最早(老)的任务出队列

6 e.execute®;

7 }

8 }

9 }

复制代码

2.4.2如何设置线程池

  • CPU密集型

尽量使用较小的线程池,一般为CPU核心数+1。 因为CPU密集型任务使得CPU使用率很高,若开过多的线程数,会造成CPU过度切换。

  • IO密集型任务

可以使用稍大的线程池,一般为2*CPU核心数。 IO密集型任务CPU使用率并不高,因此可以让CPU在等待IO的时候有其他线程去处理别的任务,充分利用CPU时间

  • 混合型任务

线程数 = CPU核心数 * (1+平均等待时间 / 平均工作时间)

2.4.3 代码示例

复制代码

1 import lombok.extern.slf4j.Slf4j;

2 import org.junit.Test;

3 ​

4 import java.util.concurrent.*;

5 ​

6 /**

7 * @description: 通过线程池实现多线程

8 * @author: DZ

9 **/

10 @Slf4j

11 public class MyThread4 {

12 //通常使用方式,定义前5个参数即可,其余默认

13 private ThreadPoolExecutor threadPoolExecutor0 = new ThreadPoolExecutor(5, 10, 60,

14 TimeUnit.SECONDS, new LinkedBlockingQueue(10));

15 ​

16 //所有参数均自定义(增加工厂ThreadFactory和拒绝方式Handle)

17 private ThreadPoolExecutor threadPoolExecutor1 = new ThreadPoolExecutor(5, 10, 60,

18 TimeUnit.SECONDS, new LinkedBlockingQueue(10), new ThreadFactory() {

19 @Override

20 public Thread newThread(Runnable r) {

21 Thread thread = new Thread®;

22 log.info(“我是线程{}”, thread.getName());

23 return thread;

24 }

25 }, new RejectedExecutionHandler() {

26 @Override

27 public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {

28 log.info(“线程被去掉{}”, new Thread®.getName());

29 }

30 });

31 ​

32 //所有参数均自定义,拒绝方式使用默认new ThreadPoolExecutor.AbortPolicy(),new ThreadPoolExecutor.DiscardOldestPolicy(),new ThreadPoolExecutor.CallerRunsPolicy(),new ThreadPoolExecutor.DiscardPolicy()

33 private ThreadPoolExecutor threadPoolExecutor2 = new ThreadPoolExecutor(5, 10, 60,

34 TimeUnit.SECONDS, new LinkedBlockingQueue(10), new ThreadFactory() {

35 @Override

36 public Thread newThread(Runnable r) {

37 Thread thread = new Thread®;

38 log.info(“我是线程{}”, thread.getName());

39 return thread;

40 }

41 }, new ThreadPoolExecutor.DiscardPolicy());

42 ​

43 @Test

44 public void testRunnable() {

45 threadPoolExecutor0.execute(new Runnable() {

46 @Override

47 public void run() {

48 log.info(“MyThread1”);

49 log.info(“MyThread2”);

50 }

51 });

52 }

53 ​

54 @Test

55 public void testCallable() throws ExecutionException, InterruptedException {

56 Future submit = threadPoolExecutor1.submit(new Callable() {

57 @Override

58 public String call() throws Exception {

59 log.info(“MyThread1”);

60 log.info(“MyThread2”);

61 return “MyThread4”;

62 }

63 });

64 System.out.println(submit.get());

65 }

66 }

复制代码

3 常见的线程池

========

3.1 FixedThreadPool


适用于任务数量已知,且相对耗时的任务

1 public static ExecutorService newFixedThreadPool(int nThreads) {

2 return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue());

3 }

3.2 SingleThreadExecutor


这种线程池非常适合所有任务都需要按被提交的顺序来执行的场景,是个单线程的串行。

复制代码

1 public static ExecutorService newSingleThreadExecutor() {

2 return new FinalizableDelegatedExecutorService

3 (new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue()));

4 }

5 ​

6 public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {

7 return new FinalizableDelegatedExecutorService

8 (new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue(),threadFactory));

9 }

复制代码

3.3 CachedThreadPool


核心线程池为0,存活时间为60s,适合小而快的任务

最后

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

Service

8 (new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue(),threadFactory));

9 }

复制代码

3.3 CachedThreadPool


核心线程池为0,存活时间为60s,适合小而快的任务

最后

[外链图片转存中…(img-AdagCK6y-1715377374530)]

[外链图片转存中…(img-ztemel0i-1715377374531)]

[外链图片转存中…(img-BUaqvcep-1715377374532)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值