Java之JVM、JUC面试题笔记(持续更新)

news/2024/11/16 7:38:19/

CountDownLatchCyclicBarrier

JUC 并发编程_juc并发编程-CSDN博客

 java 类加载机制?如何实现自定义类加载器?findClass 与 loadClass 的区别?

在Java中,自定义类加载器通常是通过继承java.lang.ClassLoader类并重写其findClass方法来实现的,该方法首先调用从文件系统获取类的字节码,然后使用defineClass方法将这些字节码转换成Class对象实例。需要注意的是,loadClass方法已经被ClassLoader实现过了,它会首先尝试调用父类加载器来加载类,只有在父类加载器加载失败的情况下,才会调用findClass方法。

自定义类加载器:

public class MyClassLoader extends ClassLoader{@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {String path="E:\\demo\\"+name+".class";try {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();Files.copy(Paths.get(path),byteArrayOutputStream);//得到class文件的字节数组byte[] bytes = byteArrayOutputStream.toByteArray();// 调用defineClass将字节码转化为Class实例return defineClass(name,bytes,0,bytes.length);}catch (IOException e){e.printStackTrace();throw new ClassNotFoundException("类文件未找到",e);}}
}

注意:在Java中,一个类的身份不仅由其完整名字(包括包名)决定,还由加载它的类加载器决定。换句话说,即使两个类来自同一份字节码文件,如果它们被不同的类加载器实例加载,那么在JVM中,它们也会被视为不同的类。

  MyClassLoader classLoader=new MyClassLoader();Class<?> aClass = classLoader.loadClass("Demo");Class<?> aClass1 = classLoader.loadClass("Demo");System.out.println(aClass==aClass1); //trueMyClassLoader myClassLoader=new MyClassLoader();Class<?> aClass2 = myClassLoader.loadClass("Demo");System.out.println(aClass==aClass2); //false

loadClass方法

loadClass是类加载的入口点。当你的代码尝试加载一个类时(通过Class.forName、反射等方式),最终都会调用到类加载器的loadClass方法。loadClass方法的主要职责是按照双亲委派模型来加载类:

  1. 检查类是否已加载:首先检查这个类是否已经被加载过了。如果已加载,就直接返回该类的Class对象。这保证了每个类在JVM内部只有一个Class实例。
  2. 双亲委派:如果类还没有被加载,loadClass会先委托给父类加载器尝试加载这个类。只有当父类加载器无法加载该类时(因为它不在父类加载器的搜索范围内),才会尝试自己加载。
  3. 调用findClass方法:如果所有父类加载器都无法加载这个类,loadClass方法最终会调用类加载器自己的findClass方法来加载这个类。

findClass方法

findClass方法是ClassLoader的一个受保护方法,它在类加载器的类加载机制中起到实际加载类的作用。当一个类加载器的父类加载器都无法加载某个类时,这个类加载器的findClass方法就会被调用。

栈会不会溢出?栈溢出一般抛什么异常?jvm 在哪里设置栈的大小?设置的参数是什
么?

如果线程请求分配的栈容量超过java虚拟机栈允许的最大容量的时候,java虚拟
机将抛出一个StackOverFlowError异常,可以通过命令行参数设置栈的大小,java -Xss512k Application,-Xms设置堆的初始大小,-Xmx设置堆的最大大小。

JIT 、逃逸分析、锁消除、栈上分配、标量替换

java 线程池?线程池构造函数的几个参数含义?keepAliveTime 解释一下?

 ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,  // 核心线程数量6,              //最大线程数60,             //空闲临时线程最大存活时间(数值)TimeUnit.SECONDS,//空闲临时线程最大存活时间(单位)new ArrayBlockingQueue<>(3),//任务队列,也就是一个堵塞队列,也可以使用LinkedBlockingQueue这个阻塞队列Executors.defaultThreadFactory(),//用线程池工具类Executors创建线程的工厂new ThreadPoolExecutor.AbortPolicy()//任务的拒绝策略中其中一个,丢弃任务并抛出RejectedExecutionException);

线程等待和唤醒的实现方式

  • Object 类下的 wait()、notify() 和 notifyAll() 方法;
  • Condition 类下的 await()、signal() 和 signalAll() 方法;
  • LockSupport 类下的 park() 和 unpark() 方法。

LockSupport 类的方法说明:

  1. LockSupport.park():休眠当前线程。
  2. LockSupport.unpark(线程对象):唤醒某一个指定的线程。

线程池拒绝策略

判断线程池中的任务已经全部执行完,等所有任务都执行完之后,进行数据的组装和返回

1. 使用 CountDownLatch 或 CyclicBarrier 等待所有线程都执行完之后,再执行后续流程。

2. CompletableFuture

ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 5, 2, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3));CompletableFuture<Void> a = CompletableFuture.runAsync(() -> {System.out.println(Thread.currentThread().getName());}, pool);CompletableFuture<Void> b = CompletableFuture.runAsync(() -> {System.out.println(Thread.currentThread().getName());}, pool);//等待两个线程执行完毕CompletableFuture.allOf(a,b).get();

ConcurrentHashMap为什么不允许插入Null

 volatile有序性

死锁

解决方案:

  1. 按照顺序加锁:尝试让所有线程按照同一顺序获取锁,从而避免死锁。
  2. 设置获取锁的超时时间:尝试获取锁的线程在规定时间内没有获取到锁,就放弃获取锁,避免因为长时间等待锁而引起的死锁。

死锁排查工具:jconsole 和 JVisualVM:这些是 Java 自带的监视工具,可以用于监视线程、内存、CPU 使用率等信息,从而帮助排查死锁问题。


http://www.ppmy.cn/news/1423112.html

相关文章

前端基础(之三)

Q1&#xff1a;介绍一下盒模型 A1&#xff1a;盒模型是用于描述Html在页面总所占空间的方式&#xff0c;盒模型将每个html元素视为一个矩形框&#xff0c;该框主要由四个主要部分组成&#xff1a;内容区域、内边距、边框和外边距。 内容区域是Html元素实际包含内容的部分&…

java | 多线程 | ThreadLocal

场景&#xff1a; web app中&#xff0c;每个request都会有一个Thread去处理&#xff0c;但是多个request可能对应一个资源&#xff1a;userInfo&#xff0c;常用ThreadLocal来存储userInfo。 网上搜&#xff0c;ThreadLocal的定义&#xff0c;大概就是&#xff1a;让每个线程…

FFmpeg: 自实现ijkplayer播放器--04消息队列设计

文章目录 播放器状态转换图播放器状态对应的消息&#xff1a; 消息对象消息队列消息队列api插入消息获取消息初始化消息插入消息加锁初始化消息设置消息参数消息队列初始化清空消息销毁消息启动消息队列终止消息队列删除消息 消息队列&#xff0c;用于发送&#xff0c;设置播放…

加载 docker 镜像文件 centos7 系统 lnmp 环境 php8.2 php5.2 php7.4

# 加载镜像从tar文件 链接&#xff1a;https://pan.baidu.com/s/1s2yf7iroI-tBTK5b9zxxnA 提取码&#xff1a;6666 docker load < my_migration_image.tar # 运行新容器&#xff0c;可以使用相同的参数和命令 8233 电脑访问时对应的端口 80 docker 上的nginx 端口号 …

初学python记录:力扣705. 设计哈希集合

题目&#xff1a; 不使用任何内建的哈希表库设计一个哈希集合&#xff08;HashSet&#xff09;。 实现 MyHashSet 类&#xff1a; void add(key) 向哈希集合中插入值 key 。bool contains(key) 返回哈希集合中是否存在这个值 key 。void remove(key) 将给定值 key 从哈希集合…

【NLP】大语言模型基础之Transformer结构

大语言模型基础之Transformer结构 1. Transformer结构总览2. 嵌入表示层2. 注意力层3. 前馈层4. 残差连接与层归一化5. 编码器和解码器结构参考文献 Transformer是一种深度学习模型架构&#xff0c;由Vaswani等人于2017年在论文《Attention is All You Need》中首次提出。它在自…

本地启用并操作Redis

本篇文章将向各位讲解redis的基础用法&#xff0c;废话不多说我们直接开始吧&#xff01; 首先需要下载redis到你本地&#xff0c;我这儿是下载到以下文件夹中&#xff1a; 双击redis-server.exe文件运行redis&#xff1a; 然后我们另外启用一个命令窗口&#xff08;需要进入你…

IOS H5页面中 HLS视频无法正常播放,使用hls.插件

IOS H5页面中 HLS视频无法正常播放&#xff0c;使用hls.插件 HLS.js依靠 HTML5 视频和 MediaSource Extensions 进行播放。 所有 iPhone 浏览器 &#xff08;iOS&#xff09; 都没有可用的 MediaSourceExtension&#xff0c;因此Hls.js将不起作用。如果您在 iPhone 上检查 Hl…