Java多线程面试题(面试必备),java多线程面试题及答案整理

  Java多线程面试题(面试必备),java多线程面试题及答案整理

  如何解决写爬虫IP受阻的问题?立即使用。

  21.什么是线程?

  线程是操作系统能够执行操作调度的最小单位。它包含在流程中,是流程中的实际操作单元。程序员可以使用它进行多处理器编程,您可以使用多线程来加速计算密集型任务。例如,如果一个线程完成一项任务需要100毫秒,那么十个线程完成任务更改只需要10毫秒。

  (更多相关面试问题推荐:java面试问答)

  12.线程和进程有什么区别?

  线程是进程的子集。一个进程可以有许多线程,每个线程并行执行不同的任务。不同的进程使用不同的内存空间,而所有的线程共享相同的内存空间。每个线程都有自己的堆栈内存来存储本地数据。

  23.如何用Java实现线程?

  两种方式:java.lang.Thread类的实例是一个线程但是需要调用java.lang.Runnable接口来执行。由于线程类本身就是被调用的Runnable接口,所以可以继承java.lang.Thread类或者直接调用Runnable接口重写run()方法来实现线程。

  14.volatile和synchronized Java关键字的作用和区别是什么?

  1、易变

  它修改的变量不保留副本,而是直接访问主存中的。

  在Java内存模型中,有主内存,每个线程也有自己的内存(如寄存器)。为了提高性能,线程会在自己的内存中保存一份要访问的变量的副本。这样,在某个时刻,同一个变量在一个线程内存中的值可能与另一个线程内存中的值或主存中的值不一致。变量被声明为volatile,这意味着它可以在任何时候被其他线程修改,因此它不能缓存在线程内存中。

  2、同步

  用它来修饰一个方法或者一个代码块的时候,可以保证最多一个线程同时执行代码。

  1.当两个并发线程访问同一个object对象中的这个synchronized(this)同步代码块时,一次只能执行一个线程。另一个线程必须等待当前线程执行完该代码块后才能执行它。

  二。然而,当一个线程访问对象的同步(这个)同步代码块时,另一个线程仍然可以访问对象中的非同步(这个)同步代码块。

  3.特别是,当一个线程访问对象的同步(this)同步代码块时,其他线程将被阻止访问对象中所有其他同步(this)同步代码块。

  四。当线程访问对象的同步(this)同步代码块时,它获取该对象的对象锁。结果,其他线程对object对象的所有同步代码部分的访问被暂时阻塞。

  动词(verb的缩写)上述规则同样适用于其他对象锁。

  25.有哪些不同的线程生命周期?

  当我们在Java程序中创建新线程时,它的状态是新的。当我们调用线程的start()方法时,状态被更改为Runnable。线程调度器将为可运行线程池中的线程分配CPU时间,并将它们的状态更改为正在运行。其他线程状态为等待、阻塞和死亡。

  26.你对线程优先级的理解是什么?

  每个线程都有优先级。一般来说,高优先级的线程在运行时会有优先级,但这取决于线程调度的实现,这是OS相关的。我们可以定义线程的优先级,但这并不能保证优先级高的线程会在优先级低的线程之前执行。线程优先级是一个int变量(从1到10),1代表最低优先级,10代表最高优先级。

  27.什么是死锁?如何分析和避免死锁?

  死锁是指两个或两个以上的线程被永远阻塞的情况,这至少需要两个或两个以上的线程和两个或两个以上的资源。

  要分析死锁,我们需要看看Java应用程序的线程转储。我们需要找出哪些线程被阻塞了,以及它们正在等待的资源。每个资源都有一个唯一的id,通过它我们可以发现哪些线程已经拥有了它的对象锁。

  避免嵌套锁、仅在需要时使用锁以及避免无限期等待是避免死锁的常用方法。

  28.什么是线程安全?Vector是线程安全的类吗?

  如果您的代码位于多个线程同时运行的进程中,这些线程可能会同时运行该代码。如果每次运行的结果与单线程运行的结果相同,并且其他变量的值与预期相同,则是线程安全的。即使线程安全计数器类的同一个实例对象被多个线程使用,也不会出现计算错误。显然,您可以将集合类分为两组,线程安全的和非线程安全的。Vector通过同步方法是线程安全的,但是它类似的ArrayList不是线程安全的。

  (相关视频教程推荐:java课程)

  29、如何在Java中停止一个线程?

  Java提供了丰富的API,但是没有提供停止线程的API。JDK 1.0最初有一些控制方法,如stop()、suspend()和resume(),但由于潜在的死锁威胁,它们在随后的JDK版本中被放弃。在那之后,Java API设计者没有提供一个兼容的、线程安全的方法来停止线程。当run()或call()方法执行完毕时,线程将自动结束。如果想要手动结束线程,可以使用volatile布尔变量来退出run()方法的循环,或者取消任务来中断线程。

  30.什么是ThreadLocal?

  ThreadLocal用于创建线程的局部变量。我们知道一个对象的所有线程将共享它的全局变量,所以这些变量不是线程安全的。我们可以使用同步技术。但是当我们不想使用同步时,我们可以选择ThreadLocal变量。

  每个线程都有自己的线程变量,它们可以使用get()\set()方法来获取它们的默认值,或者在线程内更改它们的值。ThreadLocal实例通常是您希望与线程状态相关联的私有静态属性。

  31、Sleep()、suspend()和wait()有什么区别?

  Thread.sleep()使当前线程在指定时间处于“不可运行”状态。线程总是持有对象的监视器。例如,一个线程当前在同步块或方法中,而其他线程不能进入该块或方法。如果另一个线程调用interrupt()方法,它将唤醒那个“休眠”的线程。

  注意:sleep()是一个静态方法。这意味着它只对当前线程有效。一个常见的错误是调用t.sleep(),(其中t是与当前线程不同的线程)。即使执行了t.sleep(),当前线程也会进入睡眠状态,而不是t线程。T.suspend()是一个过时的方法。使用suspend()会导致线程停止,并且线程将始终保持对象的监视器。Suspend()容易造成死锁问题。

  Object.wait()使当前线程处于“不可操作”状态。与sleep()不同,wait是对象而不是线程的方法。调用object.wait()时,线程必须先获取这个对象的对象锁。当前线程必须与锁定对象保持同步,并将当前线程添加到等待队列中。然后,另一个线程可以同步同一个对象锁来调用object.notify(),这将唤醒原来等待的线程,然后释放锁。基本上,wait()/notify()类似于sleep()/interrupt(),只是前者需要获取对象锁。

  32.什么是线程饿死,什么是活锁?

  当所有线程都被阻塞,或者所需的资源因无效而无法处理时,就没有非阻塞线程来提供资源。JavaAPI中的线程活锁可能在以下情况下发生:

  1、当程序中所有线程都执行Object.wait(0)时,wait方法的参数为0。程序将一直锁定,直到线程调用相应对象上的Object.notify()或Object.notifyAll()。

  2.当所有线程都陷入无限循环时。

  33.什么是Java定时器类?如何创建具有特定时间间隔的任务?

  Java.util.Timer是一个工具类,可用于调度线程在未来的特定时间执行。Timer类可用于调度一次性任务或周期性任务。

  Java.util.TimerTask是实现Runnable接口的抽象类。我们需要继承这个类来创建我们自己的定时任务,并使用Timer来调度它的执行。

  14.Java中同步收集和并发收集有什么区别?

  同步集和并发集都为多线程和并发提供了合适的线程安全集,但并发集具有更高的可伸缩性。

  在Java1.5之前,程序员只使用同步集,多线程并发时会导致争用,阻碍了系统的可扩展性。

  Java5引入了ConcurrentHashMap这样的并发集合,不仅提供了线程安全,还利用锁分离和内部分区等现代技术提高了可伸缩性。

  35.同步方法和同步块哪个选择更好?

  同步块是更好的选择,因为它不会锁定整个对象(当然你也可以让它锁定整个对象)。同步方法将锁定整个对象,即使该类中有多个不相关的同步块,这通常会导致它们停止执行并等待对该对象的锁定。

  36.什么是线程池?为什么要用?

  创建线程需要昂贵的资源和时间。如果有任务来了,响应时间会更长,一个进程可以创建的线程数量是有限的。

  为了避免这些问题,当程序开始响应处理时,会创建几个线程。它们被称为线程池,其中的线程被称为工作线程。

  从JDK1.5开始,Java API提供了Executor框架,以便您可以创建不同的线程池。例如,单线程池一次处理一个任务;固定数量的线程池或缓存线程池(一个可扩展的线程池,用于具有许多短期任务的程序)。

  17.Java中的invokeAndWait和invokeLater有什么区别?

  Swing API为Java开发人员提供了这两种方法,以便从当前线程而不是事件调度线程更新GUI组件。InvokeAndWait()同步更新GUI组件,比如进度条。一旦进度被更新,进度条应该相应地改变。如果进度被多个线程跟踪,则调用invokeAndWait()方法来请求事件调度线程相应地更新组件。invokeLater()方法异步调用更新组件。

  38.多线程中的忙循环是什么?

  繁忙循环是指程序员使用循环让线程等待。与wait()、sleep()或yield()等传统方法都放弃CPU控制权不同,一个繁忙的循环并没有放弃CPU,它只是在运行一个空循环。这样做的目的是保留CPU缓存。

  在多核系统中,当一个等待线程醒来时,它可能会在另一个内核中运行,这将重建缓存。它可用于避免重建缓存,并减少重建的等待时间。

  推荐:java入门。以上是java多线程面试问题的详细内容。请多关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: