面试所有线程问题小总结

为什么要使用多线程呢?

  好比是马拉车,你明明有多匹马,但是你因为不会让多匹马拉一辆车,而天天只玩一匹马拉车。是多匹马并驾一起拉车好,还是一匹马好呢?

  之前条件艰苦,没有那么多马(单核CPU),现在不一样了,随着计算机硬件发展,处理器都是多核的了。

 

目录

第一个问题,实现多线程的方式有几种?分别是?

第二个问题,既然有多种实现方式,怎么选择?有什么区别?

第三个问题,Thread的构造方法没有传Callable参数进去的,全部都是传runnable进去的,怎么办?

第四个问题,为什么要使用线程池呢?

第五个问题,线程池怎么使用的?

第六个问题: 线程池的底层原理

第七个问题,四个拒绝策略

第八个问题,在实际应用中如何使用线程池

最后一个问题,如何合理配置线程数?


第一个问题,实现多线程的方式有几种?分别是?

  •  继承Thread类。这个肯定不会用的,java是单继承的,万一类需要继承其它类,又要继承Thread,显然是可能的。同时也不符合依赖倒置原则,面向接口编程的思想。
  •  实现 Runnable接口。
  •  实现 Callable接口。
  •  使用线程池

 

第二个问题,既然有多种实现方式,怎么选择?有什么区别?

  •   同样是实现接口,Runnable和Callable又有什么区别呢?Callable可以有返回值,可以抛异常。在实际找错的时候,能够抛异常和带返回值还是很重要的,
  •   为什么有了Runnable还要有Callable呢? 并发

 

第三个问题,Thread的构造方法没有传Callable参数进去的,全部都是传runnable进去的,怎么办?

  •  找一个同时实现了Runnable接口和Callable接口的中间类。这是接口适配的精髓,需要注意,在JDK的很多的设计,都用到这个思想。

 注意上边的 get方法尽量往后放,否则会被阻塞。就违背了多个线程的意义。

 

第四个问题,为什么要使用线程池呢?

前边回答过,想要使用多线程,我们还可以使用线程池,其实这就是池的思想了。就像数据库连接池一样。

  • 首先,我们在创建线程就肯定要花费时间,线程用完需要销毁回收,也需要时间。我们使用池的思想,根据我们的需求,提前创建一些线程放在池中,这样就不用每次都去创建和销毁了。并且我们可以去对池做优化。
  • 有了池以后,会方便我们对线程的管理。
  • 线程池是这样来使用线程的,不需要new,使用提供好的Executors辅助工具类

 

 

第五个问题,线程池怎么使用的?

  • 一个线程池固定个数的线程数,使用如下:

那么工具类提供的三种形式分别什么时候用呢:

第六个问题: 线程池的底层原理

  需要特别的记住这个辅助工具类,Executors。工具辅助类所提供的三种方式底层源码都是TreadRoolExecutor,区别是里边的阻塞队列使用的不太一样。

  •  线程池的7个参数问题

  • 线程池底层工作原理

讲一遍:任务上来以后,先执行,如果有需要等待的就去阻塞队列排队,队也排满了以后就去叫帮忙干活的线程,如果还满,就到第四步拒绝了。拒绝测咯分四种。

第七个问题,四个拒绝策略

 

第八个问题,在实际应用中如何使用线程池

 首先,上Executor辅助工具类提供的三种方式是都不能使用的。原因是无界阻塞队列在实际生产线上一定会带来很大的问题。

 在阿里巴巴的开发手册中明确指明:线程池不允许使用Executor提供的。 

原因是:

 手写一个线程池:

最后一个问题,如何合理配置线程数?

分两种情况,一种是CPU密集型的(大量运算),一种是IO密集型的(大量的输入输出)

  • CPU密集型:硬件的CPU的核数+1
  • IO密集型的:因为不是一直在运算,尽可能多的配置。推荐是 硬件的CPU内核数*2
  • IO密集型的还有一种方法:核数 / (1-阻塞系数)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值