当前位置: 首页 > news >正文

并发编程面试题二

1、java线程常见的基本状态有哪些,这些状态分别是做什么的

(1)创建(New):new Thread(),生成线程对象。

(2)就绪(Runnable):当调用线程对象的star()方法,线程就会进入就绪状态,但此刻线程调度还没把该线程设置为当前线程,就是还没有获得CPU使用权。如果线程从睡眠或等待回来之后,也会进入就绪状态。

(3)运行(Running):程序将处于就绪状态的线程设置为当前线程,即获得CPU使用权,这个时候线程进入运行状态,开始运行run里面的逻辑。

(4)阻塞(Blocked):分为等待阻塞跟同步阻塞

等待阻塞:调用wait(状态就会变成WAITING状态),或调用sleep(状态就会变成TIMED_WAITING),调用join或发出IO请求。进入该状态的线程需要等待其他线程做出一定的动作(通知或中断),处于这种状态的线程CPU不会分配过来,它们需要被唤醒,也可能会无限等待下去,阻塞结束后线程重新进入就绪状态。

同步阻塞:线程在获取synchronized同步锁失败,即锁被其他线程占用,它就会进入同步阻塞状态。

(5)死亡(TERMINATED):一个线程run方法执行结束,该线程就死亡了,不能进入就绪状态。

注意:有些文档把就绪和运行两种状态统一称为 “运行中”。

等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。

超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。

2、多线程开发里面常用的方法有哪些,分别解释下

(1)sleep

属于线程Thread的方法

让线程暂缓执行,等待预计时间之后再恢复

交出CPU使用权,不会释放锁

进入阻塞状态TIMED_WAITING,睡眠结束则变为Runnable

(2)yield

属于线程Thread的方法

暂停当前线程的对象,去执行其他线程

交出交出CPU使用权,不会释放锁

不会让线程进入阻塞状态,直接变为就绪Runnable,只需要重新获得CPU使用权

作用:让相同优先级的线程轮流执行,但是不保证一定轮流

(3)join

属于线程Thread的方法

在主线程上运行调用该方法,会让主线程休眠,不会释放已经持有的对象锁

让调用join方法的线程先执行完毕,在执行其他线程

(4)wait

属于Object的方法

当前线程调用对象的wait方法,会释放锁,进入线程的等待队列

需要依靠notify或者notifyAll唤醒,或者wait(timeout)时间自动唤醒

(5)notify

属于Object的方法

唤醒在对象监视器上等待的单个线程,选择是任意的

 (6)notifyAll

属于Object的方法

唤醒在对象监视器上等待的全部线程

 3、画出线程的状态转换图和这些转换过程常用的api

4、哪些不是线程安全的数据结构(哪些是线程安全的数据结构)

ArrayList、LinkedList、HashSet、TreeSet、HashMap、TreeMap。

(Vector、Hashtable)

5、Java中可以有哪些方法来保证线程安全

  • 加锁,比如synchronize/ReentrantLock
  • 使用volatile声明变量,轻量级同步,不能保证原子性(需要解释)
  • 使用线程安全类(原子类AtomicXXX,并发容器,同步容器 CopyOnWriteArrayList/ConcurrentHashMap等
  • ThreadLocal本地私有变量/信号量Semaphore等

6、解释一下volatile关键字,还有它跟synchronized有什么区别

volatile是轻量级的synchronized,保证了共享变量的可见性,被volatile关键字修饰的变量,如果值发生了变化,其他线程立刻可见,避免出现脏读的现象。

区别:volatile保证可见性,但是不能保证可见性。

           synchronized保证可见性,也保证可见性。

7、为什么会出现脏读

JAVA内存模型简称 JMM,JMM规定所有的变量存在主内存,每个线程都有自己的工作内存,线程对变量的操作都在工作内存进行,不能直接对主内存进行。

volatile关键字修饰的变量是随时可以看到自己最新的值,假如线程1对变量v进行修改,那么线程2是可以马上看见。

使用volatile修饰变量的话,每次读取前必须从主内存属性最新的值,每次写入需要立刻写到主内存中。

8、解释下什么是指令重排

指令重排序分两类 编译器重排序和运行时重排序。JVM在编译java代码或者CPU执行JVM字节码时,对现有的指令进行重新排序,主要目的是优化运行效率(不改变程序结果的前提)。

9、解释下happens-before

先行发生原则,volatile的内存可见性就提现了该原则之一。

相关文章:

  • 从 root 一滴水看 Spring Data JPA 的汪洋大海
  • 前端面试笔试
  • 使用 Nginx 进行前端灰度发布的策略与实践
  • Day16:数组中出现次数超过一半的数字
  • harmonyOS NEXT开发与前端开发深度对比分析
  • C语言数据类型取值范围及格式化符号
  • NVMe集群:加速数据处理
  • 【C语言】自定义类型:结构体,联合,枚举(下)
  • python函数式编程
  • 【教程】继承中的访问控制 C++
  • C 语 言 --- 三 子 棋
  • 汽车保养记录用什么软件记录,汽车维修记录查询系统,佳易王汽车保养维护服务记录查询管理系统操作教程
  • 【免费】1949-2020年各省人均GDP数据
  • 2019年12月全国POI数据分享(同源历史POI分享系列)
  • Linux 蓝牙音频软件栈实现分析
  • 单引号与双引号在不同编程语言中的使用与支持
  • 【菜鸟飞】在vsCode中安装python的ollama包出错的问题
  • 高频面试题(含笔试高频算法整理)基本总结回顾21
  • C语言【内存函数】详解
  • 对比学习(Contrastive Learning)
  • 印度宣布即日起对所有巴基斯坦航班关闭领空
  • 屠呦呦当选美国科学院外籍院士
  • 美的集团一季度净利增长38%,库卡中国机器人接单增超35%
  • 腾讯重构混元大模型研发体系:成立大语言和多模态模型部,提升AI长期技术作战能力
  • 出行注意防晒补水,上海五一假期以多云天气为主最高33℃
  • 船只深夜撞上海上风机后沉没1死1失踪,调查报告公布