Java面试题整理-并发(带答案解析)

1、并发编程三要素?

  1. 原子性原子性指的是一个或者多个操作,要么全部执行并且在执行的过程中不被其他操作打断,要么就全部都不执行。
  2. 可见性可见性指多个线程操作一个共享变量时,其中一个线程对变量进行修改后,其他线程可以立即看到修改的结果。
  3. 有序性有序性,即程序的执行顺序按照代码的先后顺序来执行。

2、实现可见性的方法有哪些?

synchronized或者Lock:保证同一个时刻只有一个线程获取锁执行代码,锁释放之前把最新的值刷新到主内存,实现可见性。

3、多线程的价值?

1. 发挥多核CPU的优势

多线程,可以真正发挥出多核CPU的优势来,达到充分利用CPU的目的,采用多线程的方式去同时完成几件事情而不互相干扰。

2. 防止阻塞

从程序运行效率的角度来看,单核CPU不但不会发挥出多线程的优势,反而会因为在单核CPU上运行多线程导致线程上下文的切换,而降低程序整体的效率。但是单核CPU我们还是要应用多线程,就是为了防止阻塞。试想,如果单核CPU使用单线程,那么只要这个线程阻塞了,比方说远程读取某个数据吧,对端迟迟未返回又没有设置超时时间,那么你的整个程序在数据返回回来之前就停止运行了。多线程可以防止这个问题,多条线程同时运行,哪怕一条线程的代码执行读取数据阻塞,也不会影响其它任务的执行。

3. 便于建模

这是另外一个没有这么明显的优点了。假设有一个大的任务A,单线程编程,那么就要考虑很多,建立整个程序模型比较麻烦。但是如果把这个大的任务A分解成几个小任务,任务B、任务C、任务D,分别建立程序模型,并通过多线程分别运行这几个任务,那就简单很多了。

4、创建线程的有哪些方式?

1. 继承Thread类创建线程类
2. 通过Runnable接口创建线程类
3. 通过Callable和Future创建线程
4. 通过线程池创建,四种线程池,分别为:
1. newCachedThreadPool
2. newFixedThreadPool 
3. newScheduledThreadPool 
4. newSingleThreadExecutor 

5、创建线程的三种方式的对比?

1. 采用实现Runnable、Callable接口的方式创建多线程。

优势是:线程类只是实现了Runnable接口或Callable接口,还可以继承其他类。在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。

劣势是:编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。

2. 使用继承Thread类的方式创建多线程

优势是:编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this即可获得当前线程。

劣势是:线程类已经继承了Thread类,所以不能再继承其他父类。

3. Runnable和Callable的区别

1. Callable规定(重写)的方法是call(),Runnable规定(重写)的方法是run()。
2. Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。
3. Call方法可以抛出异常,run方法不可以。
4. 运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

6、线程的状态流转图

线程的生命周期及五种基本状态:

状态图

7、Java 线程具有五中基本状态

1. 新建状态(New):

当线程对象对创建后,即进入了新建状态,如:Threadt=newMyThread();

2. 就绪状态(Runnable):

当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;

3. 运行状态(Running):

当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;

4. 阻塞状态(Blocked):

处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才有机会再次被CPU调用以进入到运行状态。

根据阻塞产生的原因不同,阻塞状态又可以分为三种:

1. 等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
2. 同步阻塞:线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;欢迎关注公众号【码农突围】
3. 其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
4. 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
# java   面试   java面试题  

评论

企鹅群:39438021

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×