Java面试多线程

Posted shine-rainbow

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java面试多线程相关的知识,希望对你有一定的参考价值。

  1. 进程和线程的区别?

    • 进程是一个‘执行中的程序’,是系统进行资源分配和调度的一个独立单位
    • 线程是进程的一个实体,一个进程一般拥有多个线程。线程之间共享地址空间和其他资源(所以通讯和同步等操作,线程比进程更容易)
    • 线程一般不拥有系统资源,但是也有一些必不可少的资源(使用ThreadLocal存储)
    • 线程的上下文切换比进程的上下文切换要快得多<如何理解这句话?>
      • 进程切换时,涉及到当前进程CPU环境的保存和新被调度运行进程的CPU环境的设置
      • 线程切换时,仅需要保存和设置少量寄存器内容,不涉及存储管理方面的操作。
  2. 线程可以拥有属于自己独立的资源嘛?

    答:可以的,通过ThreadLocal可以存储线程的特有对象,也就是属于当前线程的资源。

  3. 进程之间常见的通讯方式?

    • 通过使用套接字Socket来实现不同机器间的进程通讯

      • 通过映射一段可以被多个进程访问的共享内存来进行通讯
      • 通过写进程和读进程利用管道进行通讯
  4. 线程的状态有哪些?

    • NEW
    • RUNNABLE
    • BLOCKED
    • WAITING
    • TIMED_WAITING
    • TERMINATED
  5. sleep和wait的区别?

    sleep方法是Thread类的静态方法,当前线程将睡眠n毫秒,线程进入阻塞状态,当睡眠时间到了,会解除阻塞,进入可运行状态,等待CPU的到来。睡眠不释放锁

    wait方法是Object的方法,必须与synchronized关键字一起使用,线程进入阻塞状态,当notify或者notifyall被调用后,会解除阻塞。但是,置于重新占用互斥锁之后才能进入可运行状态。睡眠时,会释放互斥锁。

  6. join和yield方法?

    join方法:当前线程调用,则其他线程全部停止,等待当前线程执行完毕,接着执行。

    yield方法:该方法是的线程放弃当前分到的CPU时间,但是不是线程阻塞,即线程扔处于可执行状态,随时可能再次分的CPU时间。

  7. 线程死锁的问题:死锁是最常见的一种线程活性故障。死锁的起因是多个线程之间相互等待对方而被永远暂停(处于非Runnable)。死锁产生的四个必要条件。

    1. 资源互斥:一个资源每次只能被一个线程使用
    2. 请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放
    3. 不剥夺条件:线程已经获得的资源,在未使用完之前,不能强行剥夺。
    4. 循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。
  8. 如何避免死锁的发生?

    1. 粗锁法:使用一个粗粒度的锁来消除“请求与保持条件”,缺点是会明显降低程序的并发性能会导致资源的浪费
    2. 锁指定法:(必须回答出来的点)指定获取锁的顺序,比如某个线程只能获得A锁和B锁,才能对某个资源进行操作,在多线程条件下,如何避免死锁? - ->通过指定锁的获取顺序,比如规定,只有获得A锁的线程才有资格获得B锁,按顺序获取锁就可以避免死锁。这通常被认为是解决死锁很好的一种方式。
    3. 使用显式锁中的ReentrantLock.try(Long,Timeunit)来申请锁。
  9. 谈一谈对Synchronized关键字的理解

    答:synchronized是Java的一个关键字,是一个内部锁。他可以使用在方法上和方法块上。表示同步方法和同步方法块。在多线程环境下,同步方法或者同步代码块在同一时刻只允许有一个线程在执行,其余的线程都在等待获取锁,也就是实现了整体并发中的局部串行。

  10. 谈一谈内部锁底层的实现?

    • 进入时,执行monitorEnter,将计数器+1,释放锁monitorExit时,计数器-1
    • 当一个线程判断到计数器为0时,则当前锁空闲,可以占用。反之,当前线程进入等待状态。
  11. 谈一谈你对Volatile关键字的理解?

    答:volatile关键字是一个轻量级的锁,可以保证可见性和有序性,但是不保证原子性

    解析:

    • volatile可以保证主内存和工作内存直接产生交互,进行读写操作,保证可见性
    • volatile技能保证变量写操作的原子性,不可以保证读操作的原子性
    • volatile可以禁止指令重排序(通过插入内存屏障),典型的案例是在单例模式中使用
  12. ReentrantLock和synchronized的区别?

    答:synchronized 是可重入的排它锁,和 ReentrantLock 锁功能相似,任何使用 synchronized 的地方,几乎都可以使用 ReentrantLock 来代替,两者最大的相似点就是:可重入 + 排它锁,两者的区别主要有这些:

    1. ReentrantLock 的功能更加丰富,比如提供了 Condition,可以打断的加锁 API、能满足锁 + 队列的复杂场景等等;
    2. ReentrantLock 有公平锁和非公平锁之分,而 synchronized 都是非公平锁;
    3. 两者的使用姿势也不同,ReentrantLock 需要申明,有加锁和释放锁的 API,而 synchronized 会自动对代码块进行加锁释放锁的操作,synchronized 使用起来更加方便。
  13. JVM对资源进行调度方式分为公平调度和非公平调度。

    公平调度方式:按照申请的先后顺序授权资源的独占权

    非公平调度方式:新来的线程(活跃线程)可以先被授予该资源的独占权。

    ?

以上是关于Java面试多线程的主要内容,如果未能解决你的问题,请参考以下文章

JAVA多线程和并发基础面试问答

JAVA多线程和并发基础面试问答

“面试不败计划”:Java多线程和并发基础面试问答

Java面试:投行的15个多线程和并发面试题

Java面试:投行的15个多线程和并发面试题

Java面试:投行的15个多线程和并发面试题