大家好,这里是 淇妙小屋 ,一个分享技术,分享生存的博主
以下是我的主页,各个主页同步更新优质博客,创作不易,还请大家点波关注
掘金主页
知乎主页
Segmentfault 主页
开源中国主页
后续会公布更多 MySQL,Redis,并发,JVM,分布式等面试热点常识,以及 Java 学习路线,面试重点,职业规划,面经等相干博客
转载请表明出处!
0. Java 线程面试题
0.1 线程占用的内存
- JDK1.4 默认单个线程占用 256K
- JDK1.5 默认单个线程占用 1M
- 能够通过 -Xss 参数设定
0.2 为什么要应用线程池
-
手动创立线程池的毛病
- 不受危险管制:服务器 CPU 资源无限,如果每个人都显示手动创立线程,不晓得哪里的代码呈现了多线程,在运行的时候所有线程都在抢占资源,不好管制
- 频繁创立,开销大
- 不好治理:可能无限度新建线程,可能占用过多系统资源导致死机或 OOM。而重用存在的线程,缩小对象创立、沦亡的开销,性能佳
-
线程池长处
- 升高系统资源耗费,通过重用已存在的线程,升高线程创立和销毁造成的耗费
- 进步零碎响应速度,当有工作达到时,通过复用已存在的线程,无需期待新线程的创立便能立刻执行
- 不便线程并发数的管控
1. 线程的状态
1.1 线程状态枚举
-
NEW
线程被构建,还未 start
-
RUNNABLE
运行状态
-
BLOCKED
阻塞状态,阻塞于锁
-
WAITING
期待状态
-
TIME_WAITING
超时期待状态,超过工夫自行返回
-
TERMINATED
终止状态,示意线程执行结束
1.2 线程状态转换图
2. 守护线程和线程优先级
2.1 守护线程
JVM 中不存在非守护线程时,JVM 会退出
2.2 线程的优先级
创立线程的时候能够给线程设置优先级,优先级高的线程有更高的概率调配到更多的工夫片(不相对)
3. 线程中断
能够了解为 Thread 有个 interrupted 标识符,默认为 false,示意一个线程是否被其余线程进行了中断操作
public void interrupt();// 将 Thread 的示意符设为 false
public void isInterrupted();// 返回标识符
public static isInterrupted();// 返回标识符,并设为 false
如果线程抛出 InterruptedException,那么在抛出 InterruptedException 之前,JVM 会先将标识符设为 false,而后再抛出
4. 线程间通信
4.1 通过 volatile 和 synchronized
4.2 期待 / 告诉机制
-
sleep()
以后线程进入 TIME_WAITING 状态,不会开释锁,但会开释 CPU 资源
一段时间后昏迷,回到 RUNNABLE 状态
-
yield()
以后线程由 RUNNING 状态变为 READY 状态,不会开释锁,但会开释 CPU 资源
-
wait(),notify(),nitifyAll()
- 应用 wait(),notify(),nitofyAll()时须要对 调用对象加锁(必须在同步代码块内)
- 以后线程调用某个加锁对象的 wait()后,会进入该对象的 monitor 对象的期待队列中,开释锁,开释 CPU 资源 , 状态变为 WAITING
-
以后线程调用某个加锁对象的 notify()或 nitifyAll(),期待队列中的线程从期待队列中挪动到同步队列中,线程状态由 WAITING 变为 BLOKING
期待队列中的线程要想从 wait()中返回,除了须要有其余线程调用 notify()外,还须要期待线程开释锁,取得对象的锁后能力从 wait()返回
-
join()
留神,wait()是 Object 的,join()是 Thread 的
join()中底层调用的 wait()
若调用了 thread2.join()
就是让以后线程进入 thread2 的 monitor 对象的期待队列中,晓得 thread2 完结才会被唤醒
因为底层调用的是 wait(),所以会开释锁,但留神开释的是 thread2 的锁
4.3 期待 / 告诉标准
-
期待方伪代码
synchronized(对象){while(条件不满足){对象.wait(); } 对应的解决逻辑 }
-
告诉方伪代码
synchronized(对象){ 扭转条件 对象.nitify();}