没有合适的资源?快使用搜索试试~ 我知道了~
2023年Java面试题+详细总结.docx
需积分: 5 148 浏览量
2023-01-29
10:00:14
上传
评论
收藏 32KB DOCX 举报
本文介绍了2023年Java面试题中的一个重要概念——ThreadLocal(线程变量副本),并详细总结了它的实现原理和作用。ThreadLocal采用空间换时间的方式,为每个线程维护一个本地变量,用于线程间的数据隔离,为每个使用该变量的线程提供一个副本,使得每个线程都可以独立地改变自己的副本,而不会和其他线程的副本冲突。ThreadLocal类中维护一个Map,用于存储每个线程的变量副本,Map中元素的键为线程对象,而值为对应线程的变量副本。最后,本文还介绍了ThreadLocal在Spring中的重要作用。
资源推荐
资源详情
资源评论













2023 年 Java 面试题+详细总结
ThreadLocal(线程变量副本)
Synchronized 实现内存共享,ThreadLocal 为每个线程维护一个本地变量。
采用空间换时间,它用于线程间的数据隔离,为每一个使用该变量的线程
提供一个副本,每个线程都可以独立地改变自己的副本,而不会和其他线程的
副本冲突。
ThreadLocal 类中维护一个 Map,用于存储每一个线程的变量副本,Map
中元素的键为线程对象,而值为对应线程的变量副本。
ThreadLocal 在 Spring 中发挥着巨大的作用,在管理 Request 作用域中的
Bean、事务管理、任务调度、AOP 等模块都出现了它的身影。
Spring 中绝大部分 Bean 都可以声明成 Singleton 作用域,采用
ThreadLocal 进行封装,因此有状态的 Bean 就能够以 singleton 的方式在多线
程中正常工作了。
“你能不能谈谈,java GC 是在什么时候,对什么东西,做了什么事情?”
在什么时候:
1、新生代有一个 Eden 区和两个 survivor 区,首先将对象放入 Eden 区,
如果空间不足就向其中的一个 survivor 区上放,如果仍然放不下就会引发一次
发生在新生代的 minor GC,将存活的对象放入另一个 survivor 区中,然后清空
Eden 和之前的那个 survivor 区的内存。在某次 GC 过程中,如果发现仍然又放
不下的对象,就将这些对象放入老年代内存里去。
2、大对象以及长期存活的对象直接进入老年区。
3、当每次执行 minor GC 的时候应该对要晋升到老年代的对象进行分析,
如果这些马上要到老年区的老年对象的大小超过了老年区的剩余大小,那么执
行一次 Full GC 以尽可能地获得老年区的空间。
对什么东西:
从 GC Roots 搜索不到,而且经过一次标记清理之后仍没有复活的对象。
做什么:
新生代:复制清理; 老年代:标记-清除和标记-压缩算法; 永久代:存放
Java 中的类和加载类的类加载器本身。
GC Roots 都有哪些: 1. 虚拟机栈中的引用的对象 2. 方法区中静态属性引
用的对象,常量引用的对象 3. 本地方法栈中 JNI(即一般说的 Native 方法)引
用的对象。
Synchronized 与 Loc

Synchronized 与 Lock 都是可重入锁,同一个线程再次进入同步代码的时
候。可以使用自己已经获取到的锁。
Synchronized 是悲观锁机制,独占锁。而 Locks.ReentrantLock 是,每次
不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到
成功为止。
ReentrantLock 适用场景
1、某个线程在等待一个锁的控制权的这段时间需要中断;
2、需要分开处理一些 wait-notify,ReentrantLock 里面的 Condition 应用,
能够控制 notify 哪个线程,锁可以绑定多个条件;
3、具有公平锁功能,每个到来的线程都将排队等候。
StringBuffer 是线程安全的,每次操作字符串,String 会生成一个新的对象,
而 StringBuffer 不会;StringBuilder 是非线程安全的。
fail-fast 是什么?
fail-fast:机制是 java 集合(Collection)中的一种错误机制。当多个线程对同
一个集合的内容进行操作时,就可能会产生 fail-fast 事件。
例如:当某一个线程 A 通过 iterator 去遍历某集合的过程中,若该集合的
内容被其他线程所改变了;那么线程 A 访问集合时,就会抛出
ConcurrentModificationException 异常,产生 fail-fast 事件。
happens-before
happens-before:如果两个操作之间具有 happens-before 关系,那么前一
个操作的结果就会对后面一个操作可见。
1、程序顺序规则:一个线程中的每个操作,happens- before 于该线程中
的任意后续操作。
2、监视器锁规则:对一个监视器锁的解锁,happens- before 于随后对这
个监视器锁的加锁。
3、volatile 变量规则:对一个 volatile 域的写,happens- before 于任意后
续对这个 volatile 域的读。
4、传递性:如果 A happens- before B,且 B happens- before C,那么 A
happens- before C。
5、线程启动规则:Thread 对象的 start()方法 happens- before 于此线程的
每一个动作。
Volatile 和 Synchronized 的不同点
Volatile 和 Synchronized 四个不同点:
1、粒度不同,前者针对变量 ,后者锁对象和类;

2、syn 阻塞,volatile 线程不阻塞;
3、syn 保证三大特性,volatile 不保证原子性;
4、syn 编译器优化,volatile 不优化 volatile 具备两种特性:
a. 保证此变量对所有线程的可见性,指一条线程修改了这个变量的值,新
值对于其他线程来说是可见的,但并不是多线程安全的;
b. 禁止指令重排序优化。
Volatile 如何保证内存可见性:
1、当写一个 volatile 变量时,JMM 会把该线程对应的本地内存中的共享变
量刷新到主内存。
2、当读一个 volatile 变量时,JMM 会把该线程对应的本地内存置为无效。
线程接下来将从主内存中读取共享变量。
同步:就是一个任务的完成需要依赖另外一个任务,只有等待被依赖的任
务完成后,依赖任务才能完成。
异步:不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么
工作,只要自己任务完成了就算完成了,被依赖的任务是否完成会通知回来。
(异步的特点就是通知)。 打电话和发短信来比喻同步和异步操作。
阻塞:CPU 停下来等一个慢的操作完成以后,才会接着完成其他的工作。
非阻塞:非阻塞就是在这个慢的执行时,CPU 去做其他工作,等这个慢的
完成后,CPU 才会接着完成后续的操作。
非阻塞会造成线程切换增加,增加 CPU 的使用时间能不能补偿系统的切换
成本需要考虑。
CAS
CAS(Compare And Swap) 无锁算法: CAS 是乐观锁技术,当多个线程
尝试使用 CAS 同时更新同一个变量时,只有其中一个线程能更新变量的值,而
其它线程都失败,失败的线程并不会被挂起,而是被告知这次竞争中失败,并
可以再次尝试。
CAS 有 3 个操作数,内存值 V,旧的预期值 A,要修改的新值 B。当且仅当
预期值 A 和内存值 V 相同时,将内存值 V 修改为 B,否则什么都不做。
线程池的作用
线程池的作用: 在程序启动的时候就创建若干线程来响应处理,它们被称
为线程池,里面的线程叫工作线程。
第一:降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造
成的消耗。
剩余11页未读,继续阅读
资源评论


海澜明月
- 粉丝: 21
- 资源: 2014
上传资源 快速赚钱
我的内容管理 收起
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


会员权益专享
安全验证
文档复制为VIP权益,开通VIP直接复制
