乐趣区

关于多线程:面试题多线程并发编程

基础知识

为什么要是应用并发编程

  • 晋升多核 CPU 的利用率,一般来说一台主机上的会有多个 CPU 外围,咱们能够创立多个线程,实践上讲操作系统能够将多个线程调配给不同的 CPU 去执行,每个 CPU 执行线程,这样就进步了 CPU 的应用效率,如果应用单线程就只能有一个 CPU 外围被应用。
  • 比方当咱们在网上购物时,为了晋升响应速度,须要拆分,减库存,生成订单等等这些操作。就能够进行拆分进行多线程的技术实现,面对简单业务模型,并行程序会比串行程序更适应业务需要,而并发编程更能吻合这种业务拆分。
  • 简略来说就是:

    • 充分利用多核 CPU 的计算能力。
    • 不便进行业务拆分,晋升利用性能。

多线程利用场景

例如:迅雷多线程下载、数据库连接池、分批发送短信等等。

并发编程有什么毛病

并发编程的目标就是为了能提供程序的执行效率,提供程序运行速度,然而并发编程并不总是能进步程序运行速度的,而且并发编程可能会遇到很多问题,比方:内存透露、上下文切换、线程平安、死锁等等问题。

并发编程三个必要因素是什么?

  • 原子性:即一个不可再被宰割的颗粒,操作要从头到尾一口气执行结束,不能被其余操作所中断。
  • 可见性:一个线程对共享变量的批改,另一个线程可能立即看到。
  • 有序性:程序执行的程序依照代码的先后顺序执行。(处理器可能会对指令进行重排序)

Java 程序中怎么保障多线程的运行平安的呢?

呈现线程平安问题的起因个别都是三个起因:

  1. 线程切换带来的原子性问题;解决办法:应用多线程之间同步 synchronized 或者应用锁 lock。
  2. 缓存导致的可见性问题;解决办法:synchronized、volatile、lock,能够解决可见性问题
  3. 编译优化带来的有序性问题;解决办法:happens-Before 规定能够解决有序性问题

并行并发、串行有什么区别?

  • 并发:多个工作在同一个 CPU 核上,按细分的工夫片轮流交替执行,从宏观上看这些工作如同是同时进行似的(其实不是)
  • 并行:单位工夫内,多个处理器或多核处理器同时解决多个工作,是真正意义上的“同时进行”。
  • 串行:有 n 个工作,由一个线程按程序执行。因为工作、办法都在一个线程执行所以不存在线程不平安状况,也就不存在临界区的问题。
    做一个形象的比喻:
    并发 = 俩集体用一台电脑。
    并行 = 俩集体调配了俩台电脑。
    串行 = 俩集体排队应用一台电脑。

多线程的益处

能够进步 CPU 的利用率。在多线程程序中,一个线程必须期待的时候,CPU 能够运行其余的线程而不是期待,这样就大大提高了程序的效率。也就是说容许单个程序创立多个并行执行的线程来实现各自的工作。

多线程的劣势

  • 线程也是程序,所以线程须要占用内存,线程越多占用内存也越多。
  • 多线程需协调和治理,所以须要 CPU 工夫跟踪线程
  • 线程之间对共享资源的拜访会相互影响,必须解决竞争应用共享资源的问题。

线程和过程的区别

  • 线程属于过程,线程是过程的一部分。线程不能脱离过程而存在
  • 一个过程中的多个线程能够共享一部分雷同的资源,同时还领有局部本人独有的资源例如程序计数器。而过程与过程之间个别是互相独立的,不存在内存资源共享的状况。
  • 一个过程中一个线程的解体可能会影响其余线程的运行,而一个零碎中一个过程的解体,大部分状况并不会影响其余过程的长失常运行。

什么是上下文切换?

在咱们平时的的多线程编程中,大部分状况下,咱们的创立的线程数是大于咱们主机电脑 CPU 的外围数的。而 CPU 的一个外围同一个时刻只能执行一个线程,为了可能让其余多余的线程也能被 CPU 所关照到。咱们就须要让 CPU 轮流去指向这些多余的线程,给每个线程调配一个工夫片。当一个线程的工夫片被耗费结束后,CPU 就会让这个线程进入休眠状态,让曾经进行筹备运行状态的线程取得 CPU 的使用权。这个从一个线程切换到另外一个线程的过程,就叫做上下文切换。

守护线程和用户线程有什么区别呢?

  • 用户过程:就是咱们平时 windows 电脑上前台所运行的 QQ、微信程序,或者是 Linux 服务器上运行的 Java jar 服务。
  • 守护过程:而守护过程呢,则是附丽其对应的用户过程而存在的。为其用户过程而服务,随着用户过程的沦亡,而覆灭。

如何在 Linux 上查找哪个线程 cpu 利用率最高?

  • 终端执行 top 命令,而后 shift + p 找出 cpu 利用率最高的过程 pid 号(如果是排查内存占用问题,则 shift+m)
  • 依据下面拿到的 pid 好,执行 top -H -p pid 号,而后持续按下 shift + p,找到 cpu 占有率最高的线程
  • 而后将获取到的线程 pid 号转换为 16 进制,应用 jstack 工具,jstack pid 号 > /tmp/t.dat,如 jstack 21324 > /tmp/t.dat
  • 而后 vim 方才的文件,找到线程号对应的信息

什么是线程死锁

  • 死锁是指两个或两个以上的过程(线程)在执行过程中,因为竞争资源或者因为彼此通信而造成的一种阻塞的景象,若无外力作用,它们都将无奈推动上来。此时称零碎处于死锁状态或零碎产生了死锁,这些永远在相互期待的过程(线程)称为死锁过程(线程)。
  • 多个线程同时被阻塞,它们中的一个或者全副都在期待某个资源被开释。因为线程被无限期地阻塞,因而程序不可能失常终止。
退出移动版