← 返回首页
Java多线程高频面试题
发表时间:2022-09-03 15:59:20
Java多线程高频面试题

1.进程与线程的区别

一个正在运行中的程序就是一个进程,而线程是进程的一个执行单元,是比进程还要小的独立运行的基本单位。一个程序至少包含一个进程,一个进程至少包含一个线程。

进程与线程的区别与联系主要有以下几点: 1. 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。 2. 资源拥有:同一进程内的线程共享本进程的资源,但是进程之间的资源是独立的。 3. 一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程程序稳定性更好。 4. 进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程。 5. 执行过程:每个独立的进程程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 6. 线程是处理器调度的基本单位,但进程是操作系统调度的基本单位。 7. 两者均可并发执行。

2.创建多线程有哪几种方式?

有以下三种方式: 1. 继承Thread类,因为是单根继承,不推荐使用。 2. 实现Runnable接口。 3. 实现Callabale接口。

3.Runnable与Cabllable的区别。

相同点:

  1. 两者都是接口
  2. 两者都需要调用Thread.start启动线程

不同点: 1. callable的核心方法是call,有返回值,runnable的核心方法是run,没有返回值。 2. call方法可以抛出异常,但是run方法不行。 3. callable和runnable都可以应用于executors,而thread类只支持runnable。

4.说说线程的状态转换。

  1. 新建(new):线程对象被创建后就进入了新建状态。如:Thread thread = new Thread();
  2. 就绪状态(Runnable):也被称为“可执行状态”。线程对象被创建后,其他线程调用了该对象的start()方法,从而启动该线程。如:thread.start(); 处于就绪状态的线程随时可能被CPU调度执行。
  3. 运行状态(Running):线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。
  4. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权限,暂时停止运行。直到线程进入就绪状态,才有机会进入运行状态。阻塞的三种情况:

1).等待阻塞:通过调用线程的wait()方法,让线程等待某工作的完成。 2).同步阻塞:线程在获取synchronized同步锁失败(因为锁被其他线程占用),它会进入同步阻塞状态。 3).其他阻塞:通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或超时、或者I/O处理完毕时,线程重新转入就绪状态。

  1. 死亡状态(Dead):线程执行完了或因异常退出了run()方法,该线程结束生命周期。

5.sleep与wait的区别

相同点: - sleep和wait都可以让线程进入阻塞状态,不占用CPU资源。

不同点: 1. sleep是Thread类的方法而wait是Object类的方法。 2. sleep不会释放锁,而wait方法会释放锁,使自己进入等待队列,而其它线程可以使用同步控制块或者方法。 3. wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。 4. sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常。

6.synchronized与volatile的区别

在Java多线程的开发中有三种特性:原子性、可见性和有序性。

7.synchronized与Lock的区别

synchronized与Lock的区别有以下几点:

8.说说ThreadLocal的作用

ThreadLocal也叫线程局部变量,在多线程环境可以保证各个线程里的变量独立于其它线程里的变量。也就是说 ThreadLocal可以为每个线程创建一个单独的变量副本,相当于线程的 private static 类型变量。

ThreadLocal常见的应用场景:

9.notify和notifyAll有什么区别

notify()和notifyAll()都是用来用来唤醒调用wait()方法进入等待锁资源队列的线程,区别在于:

10.阻塞与死锁的区别

用下面两幅图来形容阻塞和死锁一目了然。