东东
发布于 2022-10-28 / 19 阅读 / 0 评论 / 0 点赞

JAVA多线程面试题

wait() 和 sleep() 方法的区别

  1. 来源不同:sleep来源于Thread类,而wait方法来源于Object类;
  2. 对同步锁的影响不同:sleep不会释放锁,wait会释放锁;
  3. 使用范围不同:sleep可以在任何地方使用,wait只能在同步控制方法或同步控制块中使用,否则会抛出异常。
  4. 恢复方式不同:sleep之后,时间到了会自动恢复,wait只能通过notify或者notifyAll才能进行唤醒。

join()方法是做什么的

将其他线程临时加入,并等待其执行完成;

多线程程序的实现方式

  1. 继承Threand类;
  2. 实现Runnable接口;
  3. 实现Callable接口;
  4. 线程池;

线程的状态及流转

状态:新建、就绪、阻塞、运行、等待、终止

  1. 新建:尚未执行start()方法,还没开始运行;
  2. 就绪:已经执行start()方法,还没获取到CPU时间;
  3. 运行:当线程成功获取到CPU时间后,立即进入运行;
  4. 阻塞:进入同步方法,获取不到锁时进入阻塞;
  5. 等待:等待手动唤醒的状态,例如执行了wait方法;
  6. 终止:执行完毕退出

死锁的条件

  1. 互斥条件:一段时间内同一资源只能有一个进程使用;
  2. 请求和保持条件:进程需要请求其他资源,但是其他资源正在被其他进程使用,此时进程对手中资源又保持不释放;
  3. 不可剥夺条件:已获得的资源在进程没有使用完毕前,只能自己主动释放,不能被其他进程强制释放;

如何避免死锁

  1. 打破互斥:取消互斥,避免资源独占;
  2. 打破请求保持:进程要么一次申请到所有资源,要么就等待。或者是进程申请其他资源时,及时释放手中的资源;
  3. 打破不可剥夺:已经占用资源后无法获取到其他资源,应该及时释放原有资源

线程池的核心参数

  1. 最大线程数(超过线程池的线程为非核心线程)
  2. 线程池大小
  3. 非核心线程的存活时间
  4. 线程队列
  5. 拒绝策略:当线程池已满时,继续添加线程会触发拒绝。
    1.丢弃报错(默认)
    2.丢弃不报错
    3.丢弃队首的线程

当服务为CPU密集性时,需要扩展机器
当服务为IO密集型时,线程数一般定位CPU核心数的2倍

ThreadLocal

线程的本地变量,每当创建一个线程,都会有一个副本。
内部时通过一个map来进行存储