Java基础面试题之多线程一

1.什么是线程?

线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速。比如,如果一个线程完成一个任务要100毫秒,那么用十个线程完成改任务只需10毫秒

2.什么是线程安全?Vector是一个线程安全类吗?

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码,如果每次运行的结果和单线程运行的结果是一样的,而且其他变量的值和预期的一样,就是线程安全的。一个线程安全的计数器类的同一个实例对象在被多个线程使用的情况下也不会出现计算失误。Vector是线程安全的,和它相似的ArrayList则是线程不安全的

3.进程和线程的区别是什么?

参考文章:

      进程与线程

4.创建线程有几种不同的方式?

有四种方法

继承Thread类

实现Runnable接口

通过Callable和Future创建

使用Executor框架来创建线程池

参考文章:

        Java中创建线程的四种方法

5.什么是Callable、Future和FutureTask?

Callable类似于Runnable接口,从名字就可以看出来,但是Runnable不会返回结果,并且无法抛出返回结果的异常,Callable的功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到

可以认为Callable是带有返回值的Runnable

Future就是对于具体的Callable或者Runnable任务的执行结果进行取消、查询是否完成、获取结果,必要是可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了FutureTask,FutureTask类实现了RunnableFuture接口,而RunnableFuture接口继承了Runnable接口和Future接口,所以FutureTask既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值

Future接口表示异步任务,是还没有完成的任务给出的未来结果。所以说Callable用来产生结果,Future用来获取结果

6.什么是Executor框架?

Executor框架是一个根据一组执行策略调用,调度,执行和控制的异步任务的框架。

无限制的创建线程会引起应用程序内存溢出。所以创建一个线程池是个更好的的解决方案,因为可以限制线程的数量并且可以回收再利用这些线程。利用Executor框架可以非常方便的创建一个线程池

7.为什么使用Executor框架?

每次执行任务创建线程 new Thread()比较消耗性能,创建一个线程是比较耗时、耗资源的

调用 new Thread()创建的线程缺乏管理,被称为野线程,而且可以无限制的创建,线程之间的相互竞争会导致过多占用系统资源而导致系统瘫痪,还有线程之间的频繁交替也会消耗很多系统资源

接使用new Thread() 启动的线程不利于扩展,比如定时执行、定期执行、定时定期执行、线程中断等都不便实现

8.在Java中Executor和Executors的区别

Executors工具类的不同方法按照我们的需求创建了不同的线程池,来满足业务的需求

Executor 接口对象能执行我们的线程任务

ExecutorService接口继承了Executor接口并进行了扩展,提供了更多的方法我们能获得任务执行的状态并且可以获取任务的返回值 

使用ThreadPoolExecutor 可以创建自定义线程池

Future 表示异步计算的结果,他提供了检查计算是否完成的方法,以等待计算的完成,并可以使用get()方法获取计算的结果

9.概括的解释下线程的几种可用状态

线程在执行过程中,可以处于下面几种状态:

  • 就绪(Runnable):线程准备运行,不一定立马就能开始执行。
  • 运行中(Running):进程正在执行线程的代码。
  • 等待中(Waiting):线程处于阻塞的状态,等待外部的处理结束。
  • 睡眠中(Sleeping):线程被强制睡眠。
  • I/O阻塞(Blocked on I/O):等待I/O操作完成。
  • 同步阻塞(Blocked on Synchronization):等待获取锁。
  • 死亡(Dead):线程完成了执行    

10.同步方法和同步代码块的区别

在实际开发中,可能会出现一个方法只有2、3行代码有多线程的问题,如果使用同步方法,那么就会把方法中的所有代码都放在同步方法里面,这样做不好的地方是,此方法同一时间只允许一个线程访问该方法,其他线程无法访问,这样会严重影响代码的执行效率

如果使用同步代码块,只将可能会出现多线程问题的代码放在同步代码块里面,那么当一个线程访问同步代码块里面的代码时,其他线程也可以访问方法里其他的代码,这样代码执行效率会大大增加。所以,通常情况下,能使用同步代码块就尽量使用同步代码块

参考文章:

      同步方法和同步代码块的使用和区别

11.并行和并发有什么区别?

并行:是两个任务同时运行,系统拥有一个以上CPU,一个CPU执行一个进程,另一个CPU进行另外一个进程,两个进程同时进行,互不抢占资源,这种方式称为并行

并发:指两个任务都请求运行,而处理器只能接受一个任务,就把这两个任务安排轮流进行,由于时间间隔较短,使人感觉两个任务都在运行

简言之:

     并行是在同一时刻执行多个事件,并发是在同一时间段执行内执行多个事件

     并发编程可以充分的利用CPU,达到最高的处理性能

12.什么是守护线程?

守护线程具有最低的优先级,用于为系统中的其他对象和线程提供服务,比如GC线程,如果没有其他用户线程在运行,那么就没有可服务对象,也就没有理由继续下去

守护线程使用的情况较少,但并非没有用,比如JVM的垃圾回收、内存管理等线程都是守护线程,还有在做数据库应用时,使用的数据库连接池,连接池本身也包含着很多后台进程,监控连接个数,超时时间,状态等

守护线程和用户线程的唯一区别

猜你喜欢

转载自blog.csdn.net/ys_230014/article/details/87979083