java 高级工程师体系课第四周作业
题目 01- 请你说一说什么是线程和进程?
区别
每个进程都有独立内存空间。线程之间的堆空间和方法区共享,线程栈空间和程序计数器是独立的。线程消耗资源比进程小的多。
关系
进程里面有多个线程
线程的上下文切换是什么?
一个 CPU 内核,同一时刻只能被一个线程使用。为了提升 CPU 利用率,CPU 采用了时间片算法将 CPU 时
间片轮流分配给多个线程,每个线程分配了一个时间片(几十毫秒/线程),线程在时间片内,使用 CPU
执行任务。当时间片用完后,线程会被挂起,然后把 CPU 让给其它线程。
线程的并发与并行有啥区别?
并发(Concurrent):同一时间段,多个任务都在执行 ,单位时间内不⼀定同时执行。
并行(Parallel):单位时间内,多个任务同时执行,单位时间内一定是同时执行。并行上限取决于 CPU 核数(CPU 时间片内 50ms)
题目 02- 使用了多线程会带来什么问题呢?
能不能详细说说线程安全问题?
多个线程同时执行,可能会运行同一行代码,如果程序每次运行结果与单线程执行结果一致,且变量的预期值也一样,就是线程安全的,反之则是线程不安全。
原子性、有序性和可见性能不能深入的谈一下。
原子性:一个系列指令代码,要么全执行,要么都不执行,执行过程不能被打断
有序性:程序代码按照先后顺序执行
可见性:当多个线程访问同一个变量时,一个线程修改了共享变量的值,其他线程能够立即看到
题目 03- 什么是死锁?如何排查死锁?
排查过程最好详细说明,最少说一种排查方案,越多越好。
死锁
在多线程编程中,我们为了防止多线程竞争共享资源而导致数据错乱,都会在操作共享资源之前加上互斥锁,只有成功获得到锁的线程,才能操作共享资源,获取不到锁的线程就只能等待,直到锁被释放。
那么,当两个线程为了保护两个不同的共享资源而使用了两个互斥锁,那么这两个互斥锁应用不当的时候,可能会造成两个线程都在等待对方释放锁,在没有外力的作用下,这些线程会一直相互等待,就没办法继续运行,这种情况就是发生了死锁。
举个例子,小林拿了小美房间的钥匙,而小林在自己的房间里,小美拿了小林房间的钥匙,而小美也在自己的房间里。如果小林要从自己的房间里出去,必须拿到小美手中的钥匙,但是小美要出去,又必须拿到小林手中的钥匙,这就形成了死锁。
死锁只有同时满足以下四个条件才会发生:
互斥条件;
持有并等待条件;
不可剥夺条件;
环路等待条件;
排查如果你想排查你的 Java 程序是否死锁,则可以使用 jstack 工具,它是 jdk 自带的线程堆栈分析工具。
如果你想排查你的 Java 程序是否死锁,则可以使用
jstack
工具,它是 jdk 自带的线程堆栈分析工具。如果死锁代码例子是 C 写的,在 Linux 下,我们可以使用 pstack + gdb 工具来定位死锁问题。
pstack 命令可以显示每个线程的栈跟踪信息(函数调用过程),它的使用方式也很简单,只需要 pstack <pid> 就可以了。那么,在定位死锁问题时,我们可以多次执行 pstack 命令查看线程的函数调用过程,多次对比结果,确认哪几个线程一直没有变化,且是因为在等待锁,那么大概率是由于死锁问题导致的。
评论