0%

常见面试题的基础总结(Java多线程篇)

由于这些内容都是比较早之前进行的整理的,所以有的部分是参考了他人的博文,但是由于是之前找的,所以具体的博文链接找不到了,如果原博主看到这个文章或者有人知道其中部分内容的原博文,请与我联系,我将加上原链接,谢谢


1、进程和线程的区别

  • 运行一个程序会产生一个进程,进程包括至少一个线程
  • 每个进程对应一个JVM实例,多个线程则是共享JVM的堆
  • Java采用单线程编程模型,程序会自动创建主线程
  • 主线程可以创建子线程,原则上要后于子线程完成执行

2、Thead和Runnable什么关系

Thread是实现了Runnable接口的类,使得run支持多线程
应为类的单一继承原则,所以推荐多使用Runnable接口

3、如何给run()传参

4、如何实现处理线程的返回值

  • 主线程等待法 主线程等待子线程执行完毕
  • 使用join()阻塞当前线程等待执行完毕
  • 通过Callable接口实现:通过FutureTask或者线程池获取

如果使用FutureTask可以使用isDone方法可以判断是否执行完成

这里写图片描述

对于线程池

这里写图片描述

5、线程的状态:

  • 新建:创建后还未启动的线程
  • 运行:包含Runnable和Ready状态
  • 无限期等待:需要显式唤醒 例如没有设置Timeout参数的Object.wait()Thread.join()
  • 期限等待:在一定时间后会由系统自动唤醒 例如Thread.sleep(),设置了参数的Object.wait()Thread.join()
  • 阻塞状态:等待获取排它锁
  • 结束:已终止线程的状态,线程已经结束执行

6、sleep和wait区别

  • sleep是Thread类的方法,wait是Object类的方法
  • sleep可以在任何地方使用
  • wait只能在synchronized方法或者synchronized块中使用
  • wait是通知当前线程等待然后释放对象锁,notify也是,所以如果没有获取对象锁就是没有意义的了

7、notify和notifyAll的区别

首先建立两个概念:

锁池:假设对象A已经拥有了某个对象的锁,而其他线程想要调用这个对象的synchronize方法,所以其他线程会进入阻塞状态进入锁池等待锁的释放

等待池:假设线程A调用了某个对象的wait方法,线程A就会释放当前的锁然后进入等待池,进入等待池的线程不会去竞争锁

  • notifyAll会让所有处于等待池的线程全部进入锁池去竞争获取锁的机会
  • notify只会随机选取一个处于等待池中的线程进入锁池去竞争获取锁得机会

8、Yield

  • 当调用Thread.yield方法函数时,会给线程调度器一个当前线程愿意让出CPU使用的暗示,但是线程调度器可能会忽略这个暗示

9、如何中断线程

  • 通过调用stop()方法停止线程,通过suspendresume方法(已经弃用)
  • 调用interrupt(),通知线程应该中断了
    • 如果线程处于被阻塞状态,那么线程将立即退出被阻塞状态,并抛出一个InterruptedException异常
    • 如果线程处于正常活动状态,那么该线程的中断标志位将设置为true,被设置的中断标志位的线程将继续正常运行不受影响。
  • 正常运行的任务是,经常检查本线程的中断标志位,如果被设置了中断标志就自行停止线程
  • 如果线程处于活动状态,那么僵该线程的中断标志位设置为true,将设置中断标志的线程将继续正常运行,不受影响。

10、线程状态间的转换

这里写图片描述