JAVA面试八股文一(并发与线程)

  1. 并发的三大特性

  1. 原子性:cpu在执行过程不可以暂停然后再调度,不可以中断,要不全部执行完,要不全部不执行。

  1. 可见性:当多个线程访问同一个变量时,一个线程改变了这个变量的值,其他线程能够立即看到修改的值。

  1. 有序性:虚拟机在编译时,对改变顺序不会对最终结果影响的代码,虚拟机不一定会按照为我们写的代码顺序来执行,可能将他们重新排序。

  1. 谈谈什么是线程池

线程池和数据库连接池非常相似,用来统一管理和维护线程,减少没必要的开销

  1. 为什么要使用线程池

线程生命周期

创建》调用start方法》运行状态》run运行

因为频繁的开启或者停止线程,线程需要从新被cpu从就绪到运行状态调度,需要发生cpu的上下文切换,效率非常低。

线程池是复用机制,提前创建好固定数量的线程数一直在运行状态实现复用,限制线程创建数量 从而减少就绪到运行状态的切换。

  1. 那些地方会使用到线程池?

必须使用线程池来维护和创建线程 不能直接new Thread

异步发送短息等

  1. 线程池有那些作用?

核心点:复用机制

  1. 降低资源消耗:通过线程池创建好的线程复用,来降低线程重复创建销毁造成的资源损耗

  1. 提高响应速度:任务到达不需要再创建线程,可以直接执行

  1. 提高线程可管理性:统一i调度,管理和监控

  1. 可拓展性:例如延时定时线程池。

  1. 线程池创建方式

jdk自带的Executors 四种可缓存线程池 可定长度线程池 单例线程池,定时线程池 但是基本用不到

都是基于ThreadPoolExecutor构造函数封装的。线程数量无界,可能会出现内存溢出问题。

  1. 线程池底层复用机制和原理

  1. 提前创建一批处于运行状态的线程。 ---通过死循环实现的

  1. 提交线程任务,将任务放在并发队列容器中

  1. 正在运行的线程从任务队列中获取该任务执行

  1. ThreadPoolExecutor的核心参数

corePoolSize 核心线程数

maximumPoolSize 最大线程数

keepAliveTime 存活时间

unit keeppAliveTime 存活时间单位

  1. 线程池的线程会一直处于运行状态吗

不会,如果核心线程数corePoolSize小于,maxmumPoolSize最大线程数,多出的部分线程超过设置的存活时间keepAliveSize就会自动停止。

  1. ThreadPoolExecutor底层实现原理

  1. 创建核心线程数的线程一直处于运行状态

  1. 当队列任务数小于核心线程数时,且队列任务数未满时,将任务放入任务队列

  1. 当任务队列大于核心线程数且任务已满,

c.1若任务数小于最大线程数,创建线程执行,

c.2若任务数大于最大线程数,抛出异常,拒绝任务

  1. 线程池满了任务会丢失吗?

不会,可以缓存下来,等线程池不满的时候,再进行执行。

拒绝策略:1.丢任务,运行时抛异常 2.执行任务 3.忽视 4.从队列中提出最先进的任务 5.自定义处理器

  1. 什么是悲观锁,什么是乐观锁

悲观锁:站在mysql角度,当多个线程同时对一行数据进行修改时,只有最后一个线程才能修改成功,只要谁能获取行锁,谁就能修改该行数据,其他线程不能修改,且处于阻塞状态。

站在java锁层面:如果没有获取到锁,就会阻塞等待,后期唤醒成本非常高

乐观锁:如果没有获取到锁,当前线程不会阻塞等待,通过死循环控制,比较消耗cpu资源

  1. Mysql层面如何实现乐观锁

在表结构新增一个版本字段,version 多线程同时对一行数据实现修改操作时,铜钱查询版本号吗,作为update条件查询,如果当前版本号发生变化 数据查不到,则修改失败,mysql会不断重试,重新执行查询最新版本执行修改。

  1. java锁分类

悲观锁,乐观锁 公平锁与非公平锁 自旋锁与重入锁 重量锁与轻量锁 独占锁与共享锁

  1. 公平锁与非公平锁之间的区别

公平锁:根据请求锁的顺序排列,先请求的先获取锁,后请求的最后获取,采用队列存放

非公平锁:通过正清方式获取锁,不根据请求顺序 效率高 Synchronized是非公平锁

  1. 什么是锁的可重入性

在同一个线程中,锁可以不断传递的,可以直接获取。

  1. 什么是cas(自旋锁),它的优缺点

cas 比较并交换

没有获取的锁的线程是不会阻塞的,通过循环会一直获取锁

cas有三个操作时 内存中v,旧的预期值E,要修改的新值N

cas优点:没有获取锁的线程,会一直处在用户态,没有锁的线程一直进行循环重试。

cas缺点:通过死循环控制,cpu飙高

  1. cas如何避免aba问题?

通过加版本号来控制

  1. ThreadLocal和Synchronized区别

ThreadLocal 提供给每个线程缓存局部变量。

都可以实现线程多线程访问保证线程安全。

ThreadLocal内阁线程中都有自己独立的局部变量,空间换时间,相互间是隔离的 效率更高

Synchronized采用多个线程竞争同一个资源的时候,最终只有一个线程能访问成功,采用时间换空间的方式保证线程安全。

ThreadLocal 底层实现原理:

每个线程中都有独立的ThreadLocalMap对象 存放key value,key为当前线程,value为缓存值,get时,根据当前线程获取缓存的内容。

set get remove 方法

防止内存泄漏:

  1. 调remove方法。

  1. threadLocal设置为弱引用对象

  1. 每次做set之前都将之前的key值设置为null

  1. ThreadLocal 应用场景

SpringMVC获取http request对象

Aop LCN分布式事务,分布式服务追踪

Sping事务模板类

  1. 为什么线程缓存的时ThreadLocalMap

ThreadLocalMap可以存放n个不同的ThreadLoacal对象

每个ThreadLoacal对象只能缓存一个变量值

  1. 强,软,弱引用之间的区别

强引用:当堆内存满了,进行GC垃圾回收,对于强引用对象,就算出现了oom也不会回收

软引用:堆内存满的时候,才会回收。充足时不会回收

弱引用:只要jvm执行GC,就会被回收。

  1. ThreadLocal为何引发内存泄露问题?

内存泄漏:程序员申请了内存,但该内存一直无法释放

内存溢出:申请内存时,发现申请内存不足。

ThreadLocal = null 指针不在指向堆里的对象,但是ThreadLoacalMap中还存在指向堆对象的entry

  1. Lock锁底层实现原理

AQS+Cas +LockSupport实现

  1. AQS底层实现原理

会将没有获取锁的线程放在一个双向链表中

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java面试八股文是指在Java开发岗位面试中常见的一些核心知识点和问题。以下是Java面试八股文的主要内容: 1. Java基础知识: - Java的特点和优势 - Java的基本数据类型和包装类 - Java的运算符和表达式 - Java的流程控制语句(if-else、for、while等) - Java的异常处理机制 2. 面向对象编程: - 类和对象的概念 - 封装、继承和多态的概念和实现方式 - 接口和抽象类的区别和用法 - Java中的内部类和匿名类 3. Java集合框架: - List、Set和Map的特点和用法 - ArrayList、LinkedList、HashSet、HashMap等集合类的底层实现原理 - 集合类的遍历和常见操作 4. 多线程并发: - 线程的生命周期和状态转换 - 线程的创建和启动方式 - 线程同步与互斥的方法(synchronized、Lock等) - 线程池的概念和使用 5. JVM与垃圾回收: - JVM的内存模型和运行时数据区域 - 垃圾回收算法和垃圾回收器的选择 - 常见的JVM调优手段和工具 6. 设计模式: - 单例模式、工厂模式、代理模式等常见设计模式的原理和应用场景 - MVC、观察者模式等常见架构模式的概念和实现方式 7. 数据库与SQL: - SQL语句的基本语法和常见操作(增删改查) - 数据库事务的特性和隔离级别 - 数据库连接池的概念和使用 8. Web开发相关: - Servlet和JSP的概念和生命周期 - MVC框架(如Spring MVC)的原理和使用 - 前端技术(HTML、CSS、JavaScript)的基本知识 以上是Java面试八股文的主要内容,希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值