java线程面试题集锦(第一版本)
这两天也在找工作,抱着试试的心态,但是尽管是试试,还是应该认真,就昨天下午A厂的人了解情况,问了我一些基础题目,感觉回答的不好,因此准备花上一个月或者两个月的时间,把一些常见的面试题整理下来,答案给出一部分。
若有不全的或者是需要补充的,可以在评论区给出,我会继续完善不断发布最新的。
一、线程基础
1、什么是线程?什么是进程?他们之间有什么区别?线程的好处和坏处?(坏处从单核CPU上下文切换带来系统损耗来解答)
2、Java中实现线程有那几种方式?区别是什么?(三种或者四种,根据继承和接口特点区别)
3、Thread类中的start和run方法的区别?(start方法内部含有native的start0,官方文档解释start0内部调用了run方法)
4、守护线程和非守护线程的区别?(服务员服务顾客的例子)
5、为什么wait, notify 和 notifyAll这些方法不在thread类里面?(这些操作都是锁级别操作,每个对象都有锁,所以定义在对象中)
6、Java中什么是竞态条件? 举个例子说明。(两个线程竞争同一资源时,如果对资源的访问顺序敏感,就称存在竞态条件,导致竞态条件发生的代码区称作临界区。在临界区中使用适当的同步锁就可以避免竞态条件)
7、Java中如何停止一个线程?(从jdk1.0的stop、suspend、resume被遗弃说起,再到自然停止线程,或者使用volatile+boolean变量手动停止线程)。
8、sleep和wait的区别?
(四个:1、sleep是线程中的方法,但是wait是Object中的方法。
2、sleep方法不会释放lock,但是wait会释放,而且会加入到等待队列中。
3、sleep方法不依赖于同步器synchronized,但是wait需要依赖synchronized关键字。
4、sleep不需要被唤醒(休眠之后推出阻塞),但是wait需要(不指定时间需要被别人中断)。)
9、Java中interrupted 和 isInterruptedd方法的区别?(主要区别是前者会将中断状态清除而后者不会)
10、如何在两个线程间共享数据?(根据多个线程的代码是否相同判断是否使用同一个Runnable对象)
11、java的内存模型?(首先说出和内存结构的区别、然后是为什么需要内存模型(从计算机发展的角度来看逐步过渡到原子性、可见性、有序性),最后就是java内存模型如何解决上面三个问题);
12、有三个线程T1,T2,T3,怎么确保它们按顺序执行?(多个方法,常见的join极其机制)
13、Thread类中的yield方法有什么作用?(作用是暂停当前正在执行的线程对象,让其它有相同优先级的线程执行,静态方法,只是可能性,不能保证确定性)
14、多线程中的忙循环是什么?(忙循环就是程序员用循环让一个线程等待,不像传统方法wait(), sleep() 或 yield() 它们都放弃了CPU控制,而忙循环不会放弃CPU,它就是在运行一个空循环。这么做的目的是为了保留CPU缓存,在多核系统中,一个等待线程醒来的时候可能会在另一个内核运行,这样会重建缓存。为了避免重建缓存和减少等待重建的时间就可以使用它了。)
线程基础知识主要是线程相关的一些概念和api进行理解。
二、线程池
1、为什么要使用线程池?(反过来说,创建销毁线程的代价太高,再正过来说线程池的好处)
2、线程池有什么用?(提高效率、方便管理)
3、使用过哪些线程池?有什么使用场景?(newSingleThreadExecutor、newFixedThreadPool、newCachedThreadPool、newScheduledThreadPool,newWorkStealingPool)
4、线程池的七个参数的作用
int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler
5、线程池的工作队列(ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、PriorityBlockingQueue)
6、线程池的拒绝策略?(三种AbortPolicy、DiscardPolicy、DiscardOldestPolicy)
7、 execute和submit的区别?(execute适用于不需要关注返回值的场景,只需要将线程丢到线程池中去执行就可以,submit方法适用于需要关注返回值的场景)
8、如何终止线程池?(shutdownNow:对正在执行的任务停止,shutdown:只是不接受新任务)
三、锁系列
1、synchronized的作用、使用、底层原理、常见缺陷?
(从同步角度看作用,从对象锁和类锁角度看使用,可重入性和不可中断性看性质,从反编译字节码的角度看底层原理包含了监控器monitor,缺点是效率低、不够灵活、不知道是否获得了锁。)
2、volatile关键字的作用?(保证可见性有序性,不保证原子性,非线程安全,)
3、什么是活锁、饥饿、无锁、死锁?(死锁是相互占据对方的资源又不释放、活锁是主动释放自己的资源而不使用、饥饿是优先级高的线程一直占据资源,)
4、什么是CAS?(AtomicInteger底层实现,从A,V,B三个角度看,可以从你妈预期你女朋友A,你现在女朋友V,你妈如果看到A==V,那就让你娶B。)
5、什么是AQS?(AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的ReentrantLock,Semaphore,其他的诸如ReentrantReadWriteLock,SynchronousQueue,FutureTask等等皆是基于AQS的,
AQS核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CLH队列锁实现的,即将暂时获取不到锁的线程加入到队列中。使用了独占式和共享式,底层使用了模板方法模式)
6、什么是乐观锁,什么是悲观锁?有什么区别?
(悲观锁总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,关系型数据库里边就用到了很多这种锁机制,比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。Java中synchronized和ReentrantLock等独占锁就是悲观锁思想的实现。
乐观锁是每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。atomic
四、线程工具类
1、ThreadLocal是什么?有什么用?
ThreadLocal是一个本地线程副本变量工具类。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不通的变量值完成操作的场景。ThreadLocal就是一种以空间换时间的做法,在每个Thread里面维护了一个以开地址法实现的ThreadLocal.ThreadLocalMap,把数据进行隔离,数据不共享,自然就没有线程安全方面的问题了。
2、Semaphore有什么作用
Semaphore就是一个信号量,它的作用是限制某段代码块的并发数。Semaphore有一个构造函数,可以传入一个int型整数n,表示某段代码最多只有n个线程可以访问,如果超出了n,那么请等待,等到某个线程执行完毕这段代码块,下一个线程再进入。
3、CountDownLatch?(类似于计数器的方式,用于等待一个或多个线程执行完操作开始自身代码的执行。)
4、CyclicBarrier?(CyclicBarrier即同步屏障,它主要功能是让一组线程达到一个屏障(也可以称为同步点)是被阻塞,直到最后一个线程达到屏障是,屏障才被打开,所有被拦截的线程才会继续执行)
5、Exchanger?(用于线程间的协作工具类,主要用于线程间数据的交换。它提供了一个同步点,在这个同步点,两个线程可以交换彼此的数据)
6、 CyclicBarrier和CountDownLatch的区别?(二者的区别在于:
(1)CyclicBarrier的某个线程运行到某个点上之后,该线程即停止运行,直到所有的线程都到达了这个点,所有线程才重新运行;CountDownLatch则不是,某线程运行到某个点上之后,该线程会继续运行。
(2)CyclicBarrier只能唤起一个任务,CountDownLatch可以唤起多个任务。
(3)CyclicBarrier可重用,CountDownLatch不可重用,计数值为0该CountDownLatch就不可再用了)
线程集合将和java中的类集合一块讨论。如有不完善的地方还请补充。
image