java多线程和并发

线程相关面试题

Q:进程和线程的区别

  • 进程是系统资源分配最小单位(所有与进程相关资源被记录在进程控制块(PCB)中),线程是系统调度最小单位
  • 进程是程序在系统中的运行状态,各进程拥有独立内存地址空间,互不影响。线程只是进程的不同执行路径,一个进程内的不同线程共享进程的内存地址空间。
  • 进程的切换比线程开销大。
  • 一个java程序对应一个进程,且至少包含一个线程。

Q:start和run方法的区别

  • run方法使用当前线程,只是一个普通的方法调用
  • start方法创建新线程并启动,此时新线程为runnable状态等待系统调度并执行run方法。

Q:Thread和Runnable的区别

  • Thread是类,Runnable是接口。Thread实现了Runnable接口,使得Runnable接口中的run方法支持多线程。
  • 由于java的单一继承原则,推荐使用Runnable接口。

Q:如何处理线程的返回值

线程传参
  • 构造函数传参
  • 成员变量传参
  • 回调函数传参
获取返回值
  • 主线程循环等待
  • 使用join方法阻塞当前线程,等待子线程执行完毕。
  • 通过使用Callable,FutureTask和线程池

Q:线程的状态

  • NEW: 新创建的尚未调用start方法
  • RUNNABLE: 调用start方法(此状态包含操作系统层面的Ready和Running两种状态)
  • BLOCKED: 等待获取锁进入synchronized修饰的代码块或方法
  • WAITING: 无限期等待,不会被分配cpu时间,需要被显式唤醒。调用Object.wait()、Thread.join()会进入此状态
  • TIME WAITING: 限期等待,在等待指定时间后由系统自动唤醒。调用带参数的sleep、wait、join
  • Terminated: 终止状态,对终止状态的线程调用start会抛出IllegalThreadStateException

Q:sleep和wait的区别

基本区别
  • sleep是Thread中的静态方法,wait是Object中的实例方法
  • sleep可以在任何地方调用,wait必须在synchronized修饰的代码块或方法中调用
本质区别
  • sleep只会让出cpu资源,不会导致锁行为的改变(不释放已持有的锁)
  • wait不仅让出cpu资源,还会释放持有的同步资源锁

Q:notify和notifyAll的区别

两个概念
  • 锁池(EntryList): 假设线程A拥有一个对象的锁,而线程B想调用这个对象的某个synchronized方法或块。由于B必须先获取这个对象的锁,而这个锁此时被A持有,所以B进入阻塞状态进入一个地方去等待锁的释放,这个地方就是锁池。
  • 等待池(WaitSet): 当线程A调用某个对象的wait方法,就是释放掉持有的对象锁,同时线程A进入到该对象的等待池中,等待池中的线程不会竞争该对象的锁。直到其他线程调用该对象的notify/notifyAll方法才会唤醒等待池中的线程A,线程A会进入到锁池中竞争对象锁。

Q:yield函数作用

当调用Thread.yield()方法时,当前线程会暗示调度器愿意出让cpu使用权,但是调度器有权忽视这个暗示。

Q:如何中断线程

被废弃的方法
  • stop
  • suspend
  • resume
目前使用的方法

调用interrupt(),暗示线程应该被中断

  • 如果线程处于阻塞状态,立即退出阻塞状态并抛出InterruptException
  • 如果线程处于正常运行状态,将中断标志置为true,继续运行。

由于调用interrupt不会直接中断线程,所以需要线程不断检查中断标志位,如果为true中断运行。

线程状态和状态的切换

java多线程和并发_第1张图片

底层原理

synchronized

线程安全问题的主要诱因
  • 存在线程共享数据(临界资源)
  • 存在多条线程同时操作共享数据

解决方法
保证在同一时刻,有且只有一条线程操作数据,其他线程必须等待该线程操作完成再对数据进行操作。

互斥锁的特性
  • 互斥性: 同一时刻只有一个线程持有某个对象的锁,通过这种特性来实现多线程的协调机制。 这样在同一时刻只有一个线程对需要同步的代码块进行访问。互斥性也称为操作的原子性。
  • 可见性: 必须确保在锁被释放之前,对共享数据的修改,对于随后获得该锁的线程是可见的(即在获得锁的时候获取的是修改后的最新数据),否则另一个线程可能操作的是缓存的数据,从而引发数据不一致的问题(volatile关键字修饰的变量确保了变量的可见性)。
    synchronized锁的是对象而不是代码
互斥锁的分类
  • 对象锁: synchronized修饰的代码块和实例方法
  • 类锁: synchronized修饰的静态方法

总结:

  1. 线程A访问同步代码块或方法,线程B可以访问非同步代码块和方法
  2. 若锁住的是同一个对象,线程A访问对象的同步代码块或方法时,线程B访问同步代码块或方法被阻塞。
  3. 同一个类的不同对象的对象锁互不干扰
  4. 类锁性质同上。由于一个类只有一把对象锁,所以不同对象的同步方法访问会阻塞。
    5.类锁和对象锁互不干扰

synchronized原理

JMM内存可见性

CAS

线程池

你可能感兴趣的:(java面试)