其他
99 道 Java 多线程面试题,看完我跪了!
Java技术栈
www.javastack.cn
打开网站看更多优质文章
今天给大家更新的是一篇关于多线程面试的文章,是根据时下热门的面试内容给大家进行总结的,如有雷同,请多见谅!
1.什么是进程?
2.什么是线程?
3.线程的实现方式?
4.Thread 类中的start() 和 run() 方法有什么区别?
2.run()方法当作普通方法的方式调用。程序还是要顺序执行,要等待run方法体执行完毕后,才可继续执行下面的代码;程序中只有主线程------这一个线程, 其程序执行路径还是只有一条, 这样就没有达到写线程的目的。
5.线程NEW状态
6.线程RUNNABLE状态
7.线程的RUNNING状态
8.线程的BLOCKED状态
进入BLOCKED状态,比如调用了sleep,或者wait方法 进行某个阻塞的io操作,比如因网络数据的读写进入BLOCKED状态 获取某个锁资源,从而加入到该锁的阻塞队列中而进入BLOCKED状态
9.线程的TERMINATED状态
线程运行正常结束,结束生命周期 线程运行出错意外结束 JVM Crash 导致所有的线程都结束
10.线程状态转化图
11.i--与System.out.println()的异常
private int i = 5;
@Override
public void run() {
System.out.println("i=" + (i------------------) + " threadName=" + Thread.currentThread().getName());
}
public static void main(String[] args) {
XkThread xk = new XkThread();
Thread t1 = new Thread(xk);
Thread t2 = new Thread(xk);
Thread t3 = new Thread(xk);
Thread t4 = new Thread(xk);
Thread t5 = new Thread(xk);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
}
}
i=2 threadName=Thread-5
i=5 threadName=Thread-2
i=4 threadName=Thread-3
i=3 threadName=Thread-4
synchronized (this) {
print(x);
newLine();
}
}
12.如何知道代码段被哪个线程调用?
13.线程活动状态?
@Override
public void run() {
System.out.println("run run run is " + this.isAlive() );
}
public static void main(String[] args) {
XKThread xk = new XKThread();
System.out.println("begin --------- " + xk.isAlive());
xk.start();
System.out.println("end --------------- " + xk.isAlive());
}
}
14.sleep()方法
15.如何优雅的设置睡眠时间?
TimeUnit.HOURS.sleep(3);
TimeUnit.MINUTES.sleep(22);
TimeUnit.SECONDS.sleep(55);
TimeUnit.MILLISECONDS.sleep(899);
16.停止线程
17.interrupted 和 isInterrupted
18.yield
@Override
public void run() {
long beginTime = System.currentTimeMillis();
int count = 0;
for (int i = 0; i < 50000000; i++) {
count = count + (i + 1);
}
long endTime = System.currentTimeMillis();
System.out.println("用时 = " + (endTime - beginTime) + " 毫秒! ");
}
public static void main(String[] args) {
XKThread xkThread = new XKThread();
xkThread.start();
}
}
@Override
public void run() {
long beginTime = System.currentTimeMillis();
int count = 0;
for (int i = 0; i < 50000000; i++) {
Thread.yield();
count = count + (i + 1);
}
long endTime = System.currentTimeMillis();
System.out.println("用时 = " + (endTime - beginTime) + " 毫秒! ");
}
public static void main(String[] args) {
XKThread xkThread = new XKThread();
xkThread.start();
}
}
19.线程的优先级
20.优先级继承特性
21.谁跑的更快?
public static void main(String[] args) {
try {
ThreadLow low = new ThreadLow();
low.setPriority(2);
low.start();
ThreadHigh high = new ThreadHigh();
high.setPriority(8);
high.start();
Thread.sleep(2000);
low.stop();
high.stop();
System.out.println("low = " + low.getCount());
System.out.println("high = " + high.getCount());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class ThreadHigh extends Thread {
private int count = 0;
public int getCount() {
return count;
}
@Override
public void run() {
while (true) {
count++;
}
}
}
class ThreadLow extends Thread {
private int count = 0;
public int getCount() {
return count;
}
@Override
public void run() {
while (true) {
count++;
}
}
}
high = 1204372373
22.线程种类
23.守护线程的特点
24.Java中典型的守护线程
25.如何设置守护线程
25.Java虚拟机退出时Daemon线程中的finally块一定会执行?
public static void main(String[] args) {
Thread thread = new Thread(new DaemonRunner(),"xkDaemonRunner");
thread.setDaemon(true);
thread.start();
}
static class DaemonRunner implements Runnable {
@Override
public void run() {
try {
SleepUtils.sleep(10);
} finally {
System.out.println("Java小咖秀 daemonThread finally run ...");
}
}
}
}
26.设置线程上下文类加载器
27.join
28.什么是synchronized?
29.synchronized包括哪两个jvm重要的指令?
30.synchronized关键字用法?
31.synchronized锁的是什么?
32.Java对象头
33.Java对象头长度
34.Java对象头的存储结构
35.Mark Word的状态变化
36.锁的升降级规则
37.偏向锁
38.关闭偏向锁延迟
39.如何关闭偏向锁
40.轻量级锁
41.轻量锁的解锁
42.锁的优缺点对比
43.什么是原子操作
44.Java如何实现原子操作
45.CAS实现原子操作的3大问题
46.什么是ABA问题
47.CAS循环时间长占用资源大问题
48.CAS只能保证一个共享变量原子操作
49.volatile关键字
50.等待/通知机制
51.wait
52.notify
53.notify/notifyAll
54.等待/通知经典范式
while(条件不满足) {
obj.wait();
}
执行对应逻辑
}
改变条件
obj.notifyAll();
}
55.ThreadLocal
56.ThreadLocal使用
public static ThreadLocal threadLocal = new ThreadLocal();
public static void main(String[] args) {
if (threadLocal.get() == null) {
System.out.println("未设置过值");
threadLocal.set("Java小咖秀");
}
System.out.println(threadLocal.get());
}
}
Java小咖秀
57.解决get()返回null问题
static ThreadLocalExt threadLocalExt = new ThreadLocalExt();
@Override
protected Object initialValue() {
return "Java小咖秀";
}
public static void main(String[] args) {
System.out.println(threadLocalExt.get());
}
}
58.Lock接口
59.Lock接口提供 synchronized不具备的主要特性
60.重入锁 ReentrantLock
61.重进入是什么意思?
62.ReentrantLock默认锁?
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
63.公平锁和非公平锁的区别
64.读写锁
读写锁允许同一时刻多个读线程访问,但是写线程和其他写线程均被阻塞。读写锁维护一个读锁一个写锁,读写分离,并发性得到了提升。
65.LockSupport工具
66.Condition接口
67.Condition使用
Lock lock = new ReentrantLock();
Condition cd = lock.newCondition();
public void await() throws InterruptedException {
lock.lock();
try {
cd.await();//相当于Object 方法中的wait()
} finally {
lock.unlock();
}
}
public void signal() {
lock.lock();
try {
cd.signal(); //相当于Object 方法中的notify()
} finally {
lock.unlock();
}
}
}
68.ArrayBlockingQueue?
69.PriorityBlockingQueue?
70.DelayQueue?
71.Java并发容器,你知道几个?
72.ConcurrentHashMap
73.ConcurrentLinkedQueue
74.什么是阻塞队列?
75.阻塞队列常用的应用场景?
76.Java里的阻塞的队列
LinkedBlockingQueue:链表结构组成的|有界阻塞队列
PriorityBlockingQueue: 支持优先级排序|无界阻塞队列
DelayQueue:优先级队列实现|无界阻塞队列
SynchronousQueue:不存储元素| 阻塞队列
LinkedTransferQueue:链表结构组成|无界阻塞队列
LinkedBlockingDeque:链表结构组成|双向阻塞队列
77.Fork/Join
78.工作窃取算法
79.工作窃取算法的有缺点
80.Java中原子操作更新基本类型,Atomic包提供了哪几个类?
81.Java中原子操作更新数组,Atomic包提供了哪几个类?
82.Java中原子操作更新引用类型,Atomic包提供了哪几个类?
83.Java中原子操作更新字段类,Atomic包提供了哪几个类?
84.JDK并发包中提供了哪几个比较常见的处理并发的工具类?
85.CountDownLatch
86.CyclicBarrier
87.CountDownLatch与CyclicBarrier区别
88.Semaphore
89.Exchanger
90.为什么使用线程池
降低系统消耗:重复利用已经创建的线程降低线程创建和销毁造成的资源消耗。 提高响应速度:当任务到达时,任务不需要等到线程创建就可以立即执行。 提供线程可以管理性:可以通过设置合理分配、调优、监控。
91.线程池工作流程
92.创建线程池参数有哪些,作用?
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
CallerRunsPolicy: 调用者所在的线程来运行任务。
DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。
DiscardPolicy:不处理,直接丢掉。
当然可以根据自己的应用场景,实现RejectedExecutionHandler接口自定义策略。
93.向线程池提交任务
94.关闭线程池
95.线程池如何合理设置
任务是cpu密集型、IO密集型或者混合型
任务优先级,高中低。
任务时间执行长短。
任务依赖性:是否依赖其他系统资源。
96.Executor
97.Executor框架的主要成员
98.FixedThreadPool
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());}
99.CachedThreadPool
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());