面试必看,多线程并发面试题合集

什么是java中的线程?线程可以理解为一个轻量化进程。是进程的最小部分,可以与进程的其他部分(线程)并发执行。什么是多线程?多线程是多个线程并发执行。Java支持多线程,因此它允许应用程序并发执行两个或多个任务。在java中创建线程的方法是什么?有两种方式创建线程:​ 继承Thread类​ 实现Runnable接口但是本质上最终都是创建Thread类。Thread和Runnable哪个更好?实现Runnable接口被认为是比继承Thread类更好的方法,原因如下:Java不支持多重继
摘要由CSDN通过智能技术生成

什么是java中的线程?

线程可以理解为一个轻量化进程。是进程的最小部分,可以与进程的其他部分(线程)并发执行。

什么是多线程?

多线程是多个线程并发执行。Java支持多线程,因此它允许应用程序并发执行两个或多个任务。

在java中创建线程的方法是什么?

有两种方式创建线程:

​ 继承Thread类

​ 实现Runnable接口

但是本质上最终都是创建Thread类。

Thread和Runnable哪个更好?

实现Runnable接口被认为是比继承Thread类更好的方法,原因如下:

  • Java不支持多重继承,所以如果你继承Thread类,你不能继承任何其他类,但是在多数情况下需要再集成其他类。
  • Runnable接口代表一个任务,它可以通过Thread类或Executors的执行。
  • 当使用继承时,是因为想要扩展父类的一些属性,修改或改进类的行为。但是如果你只是为了创建线程而集成Thread类,那么可能不太符合面向对象思想。

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

  • 进程可以被称为正在执行的程序,而线程是进程的一部分。
  • 进程中可以有多个线程,而线程是可以与其他线程并发执行的最小单元。
  • 进程有自己的内存空间,而多个线程共享相同的进程内存空间。每个线程有自己的堆栈。
  • 进程是相当重量级的,有更多的开销,而线程是轻量级的,开销更少。
  • 进程之间相互对立,而线程之间不是,因为它们共享内存空间。
  • 在进程中不需要同步,线程需要同步以避免意外的场景。
  • 可以通过调用线程的start方法轻松创建新线程,但创建进程则需要复制父进程的资源来创建新的子进程。

java中的sleep和wait有什么区别?

在说区别之前,需要先了解sleep和wait的作用。

sleep

  • 会导致当前执行的线程休眠特定的时间;
  • 它的准确性取决于操作系统的计时器和调度程序;
  • 不会释放已经获得的monitors,因此如果从同步代码中调用它,其他线程不能进入该块或方法;
  • 调用interrupt()方法可以唤醒sleep的线程。
synchronized(lockedObject) {
      
    Thread.sleep(1000); // 不会释放锁
    // 只有当1000ms之后,或者调用interrupt方法,才会唤醒
}

wait

  • 让当前线程等待,直到另一个线程调用该对象的notify()方法或notifyAll()方法;
  • 必须在同步代码中调用。这意味着在调用wait()方法之前,当前线程必须已经获得该对象的锁;
  • 调用wait方法会释放对象上的锁并将当前线程添加到等待队列中,这样另一个线程就可以获得该对象上的锁。
synchronized(lockedObject) {
      
    lockedObject.wait(); // 会释放lockedObject上的锁
    //因此,只有其他线程调用notify()或notifyAll(),它才会被唤醒
}
Parameter wait sleep
是否同步 如果不在synchronized中调用wait,它会抛出IllegalMonitorStateException It 不需要在同步代码中调用。
调用方式 wait方法是对Object的操作,定义在Object类中 sleep方法操作的是线程,所以定义在Thread类中
释放锁 调用wait方法会释放锁 sleep方法不会释放锁
唤醒条件 调用notify()或notifyAll() 睡眠时间到达或者调用interrupt()
是否静态 wait方法不是静态方法 sleep是静态方法

为什么wait(), notify()和notifyAll()方法在Object类中?

线程wait和notify是基于同一个对象锁进行的等待和通知机制。

如果wait(), notify()和notifyAll()定义在线程类中,那么每个线程都必须知道另一个线程的状态,这是没有意义的,因为每个线程都是独立于其他线程运行的,并且对其他线程没有特定的标识。

为什么只能在同步代码块调用wait和notify方法?

调用wait()线程就可以等待,线程必须放弃锁。

要放弃锁,线程必须首先拥有它。而获得锁是进入同步上下文的前提。

如果在同步上下文之外调用wait方法,那么它将抛出IllegalMonitorStateException

java中线程的状态?

在java中有5种线程状态:

New:当创建一个线程对象还没有激活时的状态。

Runnable:当调用线程的start方法时,线程进入runnable状态。它是立即执行还是经过一段时间后执行,取决于线程调度程序。

Run:当线程正在执行时,它进入运行状态。

Block:当线程等待某些资源或其他线程完成时,它将进入阻塞状态。

Dead:当线程的run方法执行完毕后时,线程进入dead状态。

可以直接调用run方法来启动一个线程吗?

不能直接调用run方法来启动线程。你需要调用start方法来启动一个新线程。

直接调用run方法,不会创建一个新线程,会在主线程中直接执行。

我们可以在java中两次启动同一个线程吗?

不可以,一旦启动了一个线程,它就不能再启动了。 如果尝试再次启动线程,它将抛出IllegalThreadStateException

如何让主线程等待其他所有线程执行完毕再结束?

可以使用join()方法来实现。

什么是守护线程?

守护线程是为用户线程提供服务的低优先级后台线程。 它的生命取决于用户线程。 如果没有用户线程在运行,那么即使守护进程线程在运行,JVM也可以退出。 JVM不会等待守护线程完成。

如何将用户线程更改为守护线程?

setDaemon(true)方法可以将用户线程改为守护进程。

同步是什么?

同步是将对共享资源的访问限制在一个线程的能力。 当两个或多个线程需要访问共享资源时,必须有某种机制使共享资源只被一个线程使用。 这种机制称为同步。

如何实现同步?

可以通过一个例子来更好的理解同步。

假设我们要对一个url的请求次数进行统计,我们通过下面代码来实现:

非同步方式

public class RequestCounter {
   
 
 private int count;
 
 public int incrementCount()
 {
   
 count++;
 return count;
 }
}

这是没有同步机制的实现方式,如果有两个请求同时到达时,如线程T1在count=10时加1,同时线程T2也对count=10加一,最后的结果会是11,但是实际上的请求数是12,造成数据不一致。

同步方式

同步可以通过synchronized代码块或或者synchronized方法。

public class RequestCounter {
   
 
 private int count;
 
 public synchronized int incrementCount()
 {
   
  count++;
  return count;
 }
}

这种方式下,同一时间只能有一个线程执行incrementCount(),另一个线程只能等获得锁的线程执行完成释放锁之后执行。

public class RequestCounter {
   
 
 private int count;
 
 public int incrementCount() {
   
  synchronized (this) {
   
   count++;
   return count;
  }
 }
}

对象锁和类锁的区别?

对象锁

对象锁定意味着需要同步非静态方法或块,以便它一次只能被该实例的一个线程访问。如果您保护非静态数据,则使用它。

同步方法和同步代码块使用的是对象锁。

public synchronized int incrementCount(){
   
}

同步代码块

public int incrementCount() {
   
    synchronized (this) {
   
        count++;
        return count;
    }
}

或者在其他对象上使用synchronized块:


                
  • 7
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小黑说Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值