[面试准备]高并发与多线程

169 阅读5分钟

关键字

线程与进程

  • 线程和进程的概念、并行和并发的概念
    1. 进程与线程之间有什么区别?
      1. 进程是资源分配和调度的基本单元
      2. 线程是程序执行的最小单位
    2. 进程、线程都各有什么特点?
    3. 进程之间的是怎么进行交互的呢?
    4. 什么是缓冲区溢出? 结合内存溢出的问题来看,java存在内存溢出吗?当然存在的,内存的溢出主要是程序的问题。
    5. 进程之间如何进行交互? 通过tcp/ip端口
    6. 线程之间如何进行交互? 通过访问同一共享变量实现交互

一篇让你明白进程与线程之间的区别与联系

  • 创建线程的方式及实现

    1. 实现runnable接口
    Thread thread1 = new Thread(() -> {
        //run()方法的实现
    });
    
    1. 实现callable接口(需要搭配future才可以获取返回值)
    2. 继承Thread类
    3. 使用线程池
  • 线程的状态、生命周期以及状态是如何转移的

    • 线程的状态:

      • new
      • runnable
      • blocked
      • waiting
      • time_waiting
      • terminated
    • 线程的生命周期:

      • 新建
      • 就绪
      • 运行
      • 阻塞
      • 销毁
    • 常用方法 参考:Java线程中yield与join方法的区别

      • start:让线程进入可运行状态,待获得时间片之后可以立刻执行|状态从new->runnable|
      • run:线程的执行体
      • 为什么要用start来启动线程
        • start和run分离后,多线程就成为了可能
        • start使线程的使用更为灵活
      • yield:让出当前线程的执行权|从执行状态变为可执行状态|线程不会阻塞
      • join:在当前线程的执行周期内插入其它线程的执行|当前线程状态变为blocked直到这个线程实例执行完成|阻塞当前线程

      thread join的用法

      • wait
        • wait方法能不能被重写,wait能不能被中断;
  • 一个线程连着调用start两次会出现什么情况? 抛出异常(根据threadStatus ==0判断)

  • 为什么不允许多次调用start? 因为无法保证线程的执行状态,start只是表示这个线程是具备执行条件,并非立即执行。

    • 一来是确实没有必要多次执行。
    • 二来start方法是与操作系统交互,这部分工作也是有一定的开销啊。
    • 三来线程start时会被加入threadgroup中,便于对线程批量管理,没有设置,默认加入系统的threadgroup,是一个加了synchronize的数组。如果支持重复start,还需要判断重复元素,设计就复杂了。
  • daemon线程

  • 线程的中断是怎么使用的

  • 内核线程、用户线程

多线程与线程池

  1. 为什么需要多线程
    1. 首先解释为什么需要线程? 线程和进程的区别不用多说,参见进程和线程的区别。
    2. 为何单线程不行非要用多线程呢?
      • 为了适应更复杂的应用场景,比如后台任务、异步处理、定时任务等等。
      • 提高处理器的性能(抢占式调度)

线程安全

  1. 说说线程安全问题,什么是线程安全,如何保证线程安全?

    • 什么是线程安全 线程安全,就是说在多线程的场景下,无需考虑任何同步、线程调度切换的事情,调用这个对象的行为都可以获得正确的结果。
    • 如何保证线程安全? 首先我们要看多线程编程的特点,有原子性、可见性和有序性。

    保证线程安全常用的手段是锁和共享变量。

    用锁其实是把并发变成了顺序执行,在同一时刻只有一个线程可以获得资源,其他线程如果要获取锁,那只能排队等待。用锁自然可以实现以上一个特性,不过锁的开销较大。

  2. ThreadLocal 原理分析

  3. ThreadLocal为什么会出现OOM

  4. 出现的深层次原理

CAS实现

  1. CAS机制会出现什么问题;
  2. 什么是ABA问题,出现ABA问题JDK是如何解决的

AQS

队列同步器

线程安全队列实现

线程安全map实现

在java基础详细看

线程池

  1. 讲讲线程池的实现原理
  2. 线程池的几种实现方式
  3. 线程池的实现?四种线程池?重要参数及原理?任务拒接策略有哪几种?

  1. synchronized与ReentrantLock哪个是公平锁;

  2. synchronized与Lock的区别

  3. 常用的避免死锁方法;

  4. 重入锁的概念 我们在实际工作中会发现,同一个线程获取锁的概率非常大。

  5. 重入锁为什么可以防止死锁 产生死锁的场景是,在子类调用父类的方法,子类的方法和父类的方法都是用synchronized加了锁。

参考:Java可重入锁如何避免死锁

  1. 可重入锁的实现原理

    • 新增属性
      • 当前锁资源归属线程
      • 重入锁获取次数
    • 获取锁时,如果资源被锁住,判断是否归属当前线程,是计数+1
    • 释放锁时,计数-1,只有当计数为0时,才表示锁被真正释放。
  2. 产生死锁的四个条件(互斥、请求与保持、不剥夺、循环等待)

  3. 如何检查死锁(通过jConsole检查死锁)

  4. CAS无锁的概念、乐观锁和悲观锁

  5. 乐观锁的业务场景及实现方式

  6. 偏向锁、轻量级锁、重量级锁的概念

  7. 互斥锁与自旋锁 参考:自旋锁替代互斥锁使用场景

  8. 手写一个自旋锁

  9. 锁粗化与锁消除 参考:Java锁消除和锁粗化

concurrent包下常用工具

  1. 说说 CountDownLatch、CyclicBarrier 原理和区别

大白话说java并发工具类-CountDownLatch,CyclicBarrier

1. CountDownLatch
    1. await:这个方法需要等待countDown的值为0,才可以继续执行
    2. countDown:countDown值减1
    3. 与join的区别:底层原理一致
2. CyclicBarrier
  1. 说说 Semaphore 原理

JUC 中提供的限流利器-Semaphore

  1. 说说 Exchanger 原理

Java:Exchanger类的作用

  1. AtomicInteger底层实现原理;

深入解析Java AtomicInteger原子类型