Java并发编程高频面试题汇总

1.为什么要使用并发编程?有什么缺点?

充分利用多核CPU的计算能力,提高程序的执行效率,提高程序运行速度。

缺点就是容易造成内存泄漏,上下文切换,线程安全,死锁等问题。

2.并发编程三要素是什么?怎么保证多线程的安全?

原子性:原子是一个不可再分割的单位。原子性指的是一个或多个操作要不全部执行成功要么全部执行失败。

可见性:一个线程对共享变量的修改,其他的线程可以立刻看到。

有序性:程序执行的顺序按照代码的先后顺序执行。

线程切换会带来原子性问题,缓存会导致可见性问题,编译优化带来有序性的问题。

JDK的Atomic类,synchronized,LOCK可以解决原子问题。volatile可以解决可见性问题。Happens-Before 规则可以解决有序性问题。

3.线程和进程的区别?

进程是内存中运行的一个程序,每个进程都有自己独立的内存空间。

线程是进程中的一个执行任务,一个进程可以有多个线程,多个线程之间可以共享数据。

进程是操作系统资源分配的基本单位,线程是处理器任务调度和执行的基本单位。每个进程之间都有独立的代码和数据空间,程序之间的切换开销比较大,线程是轻量级的进程,同一个进程中的线程共享代码和数据空间,每个线程有自己独立的运行栈和程序计数器,线程之间开销比较小。

4.创建线程的四种方式?

继承Thread类,实现Runable接口,事项Callable接口,使用线程池创建。

5.线程的基本状态和操作?

新建状态:新创建一个对象。

就绪状态:当线程调用start方法是处于就绪状态。

运行状态:  就绪状态的线程获取CPU时间片,执行程序代码。

阻塞状态:处于运行状态的线程因为某种原因,放弃CPU的使用权,停止执行,此时进入阻塞状态。知道再次进入就绪状态才能够获取CPU执行权。

死亡状态:run方法,main方法结束,或者因为异常退出了run方法,该线程的结束生命周期。

6.Java中垃圾回收有什么目的?什么时候进行垃圾回收?

垃圾回收的目的是识别并且丢弃不再使用的对象来释放和重用资源。

当虚拟机空闲和内存使用不足的时候会进行垃圾回收。

7.synchronized 的作用使用的三种方式?

synchronized 关键字用来控制线程同步,在多线程的情况下,synchronized 代码块不会被多个线程同时执行。

synchronized 关键字可以使用修饰实例方法,静态方法,代码块。

修饰实例方法拿到的是当前对象实例加锁。修饰静态方法是对当前类加锁。修饰代码块是给对象实例加锁。

8.volatile关键字的作用?可以创建volatile数组吗?

保证共享变量的可见性和禁止指令重排,volatile一个重要的作用是和CAS一起使用保证原子性。可以创建volatile数组,不过只是指向一个数组的引用。

9.synchronized 和volatile有什么区别?

Volatile只能保证变量可见性不能保证原子性。synchronized 可以保证变量修改的可见性也可以保证原子性。Volatile是线程轻量级的实现,性能比synchronized 要好一点,但是volatile只能修饰变量而synchronize可以修饰方法和代码块。

10.Lock接口是什么?它有什么优势?

Lock接口时synchronized 的扩展版,Lock提供无条件的,可轮询的,定时的,可中断的,可多条件队列的锁操作。Lock接口的实现类支持公平锁和非公平锁。

优势:可以使锁更公平。可以使线程等待锁的时候中断。可以让线程尝试去获取锁,如果获取不到锁立即返回或者等待一段时间。可以在不同的范围,以不同的顺序获取和释放锁。

11.什么是死锁?产生死锁的必要条件?

死锁就是两个以上的线程在执行过程中,因为争夺资源而造成的一种互相等待的现象。若无外力作用,它们谁都无法推进下去。

必要条件:互斥条件,请求与保持条件,不可剥夺条件,循环等待条件。

12.ThreadLocla是什么?有哪些应用场景?

ThreadLocal是一个本地线程副本变量工具类,每个线程都创建一个ThreadLocalMap对象,ThreadLocal就是一种以空间换时间的做法,每个线程可以访问自己内部ThredLocalMap的value。通过这种方式避免资源在多线程成之间共享。

原理:现场局部变量是属于线程内部的变量,属于线程自身私有的,不存在线程共享。Java提供ThreadLoaclMap机制是为了保障线程安全,但是在管理环境下使用线程变量的时候要特别小心,工作线程的生命周期比任何变量的生命周期都要长。任何线程局部变量一旦在工作完之后没有释放会造成内存泄漏问题。

经典使用的场景是为每一个线程分配JDBC的连接Connection。这样就可以保证每个线程都在各自的Connection上进行数据库的操作。

13.什么是线程池?怎么创建线程?使用线程池有什么好处?

线程池顾名思义就是事先创建若干个可执行的线程放入一个池中。需要的时候直接去线程池中去取不用创建,使用完毕不用销毁线程而是放回池中,从而减少创建和销毁线程对象的开销。

ThreadLocalExecutor()是最原始的创建线程方式,也是阿里巴巴Java开发手册中明确规范的创建线程池的方式。

使用线程池可以降低资源消耗,提高资源的利用率,提高线程的可管理性。

14.ThreadLocalExecutor的参数功能?

三个核心的参数

CoreSzie:核心线程的数量。线程定义了最小可以运行多少线程。

MaximumPoolSize:最大线程数,线程池中允许存在最大的线程数。

WorkQueue:当新任务来的时候会先判断当前运行的线程数量是否达到了核心线程数,如果已经达到就会被放到队列中。

KeepAliveTime:线程池中的线程数量大于核心线程数的时候,如果没有任务提交,会等时间超过keeAliveTime才会被回收销毁。

Unit:keepAliveTime的时间单位。

ThreadFactory:为线程池创建新线程的工厂。

Handler:线程池任务队列超过最大线程数之后的拒绝策略。

 

15.讲一下原子操作类,底层实现原理是什么?

Atomic原子类基本的特性就是在多线程环境下当有多个线程对单个变量进行操作时,仅有一个线程能成功,未成功的线程可以像自旋锁一样,继续尝试,一直等到执行成功。

AtomicInteger类主要使用CAS+volatile和native方法保证原子性。避免synchronized的高开销,执行效率提升。

16.Java中CountdownLatch和CycliBarriar的区别是什么?

CountdownLatch一般用于某个线程A等待其他线程执行完成之后它才执行。

CycliBarriar一般用于一组线程互相等待至某个状态,然后一组线程再同时执行。

CountdownLatch调用countDown方法当前线程不会阻塞会继续执行下去,CycliBarriar的await方法,会阻塞当前现场,直到指定的线程到达了指定点的时候,才会继续往下执行。

你可能感兴趣的:(java,面试)