网站建设演示ppt模板下载,网站怎么做移动端适配,网站建设推广平台,淘宝客网站做一种还是做好几种附录#xff1a;精选面试题 Q#xff1a;为什么虚拟机必须保证一个类的Clinit( )方法在多线程的情况下被同步加锁 #xff1f; A: 因为虚拟机在加载完一个类之后直接把这个类放到本地内存的方法区#xff08;也叫原空间#xff09;中了#xff0c;当其他程序再来调这个类… 附录精选面试题 Q为什么虚拟机必须保证一个类的Clinit( )方法在多线程的情况下被同步加锁 A: 因为虚拟机在加载完一个类之后直接把这个类放到本地内存的方法区也叫原空间中了当其他程序再来调这个类的时候直接从内存中拿的因此Clinit( )方法只会执行一次来保证类只会被加载一次当同时有两个线程进来操作同一个类的Clinit( )方法可能会出现数据的不一致性当两个线程中的某个线程抢到了类锁而且一直在Clinit方法中执行另一个线程会一直保持阻塞状态 Q: 类加载子系统中的加载阶段分别有哪些类加载器 A: 一般会有BootStarpClassLoader引导类加载器ExtClassLoader扩展类加载器ApplicationClassLoder应用类加载器。 Q: 类加载器又分为几种 A: 从官方给的规范来讲分为两种类加载器分别是引导类加载器和自定义类加载器。引导类加载器BootStarpClassLoader是由C语言和C进行编写的主要加载Java的核心类库。而直接或间接继承ClassLoader的加载器都可以认为是自定义类加载器JVM默认提供给用户使用的是继承图最底层的ApplicationClassLoader系统类加载器ApplicationClassLoader调用getParent( )方法一直往上面调是获取不到BootStarpClassLoader引导类加载器的。 一、内存结构 当class文件以二进制流的方式加载到JVM内存的类加载子系统时在类加载子系统Class Loader SubSystem中又分三步对数据进行解析分别是加载阶段Lading链接阶段Linking初始化阶段Initiatlizetion。 加载阶段有引导类加载器(BootStrapClassLoader)扩展类加载器(ExtensionClassLoder)系统类加载器(ApplicationClassLoder)和自定义加载器。 链接阶段验证(Verify)准备(Prepare)解析(Resolve)。 最后把数据一起放入初始化阶段。 二、类加载器和类加载过程 ClassLoader 只负责class文件的加载至于是否可以运行则有ExecutionEngin(执行引擎) 决定。 Loading加载阶段 链接阶段Linking 初始化阶段Initiatlizetion 程序加载到初始化阶段clinit( )方法会收集静态变量赋值的动作在连接阶段Linking先为静态变量(类变量)赋0值当程序走到初始化阶段从上到下收集赋值动作赋值给静态变量。 当类中没有声明过静态变量或者静态代码块时类加载子系统在进行到初始化阶段时就不会创建clinit( )方法。 变量声明在静态代码块的后面可以在静态代码块进行赋值但不能进行调用报错信息为 “非法的前向引用” 任何一个类都会有 init( )方法用来初始化类对象但不都有Clinit( )方法用于收集静态变量供该类全局使用 Q为什么虚拟机必须保证一个类的Clinit( )方法在多线程的情况下被同步加锁。 A: 因为虚拟机在加载完一个类之后直接把这个类放到本地内存的方法区也叫原空间中了当其他程序再来调这个类的时候直接从内存中拿的因此Clinit( )方法只会执行一次来保证类只会被加载一次当同时有两个线程进来操作同一个类的Clinit( )方法可能会出现数据的不一致性当两个线程中的某个线程抢到了类锁而且一直在Clinit方法中执行另一个线程会一直保持阻塞状态。 三、类加载器的分类 下面这一张图的几种类加载器是等级关系例如文件目录上下级。但绝不能理解为是 继承关系。BootClassLoader是用C和C编写的而下面的几个类加载器是Java语言编写的都间接继承了ClassLoader。 是一种像文件夹一样的包含关系。A文件夹包含B文件夹B文件夹又包含着C文件夹ClassLoader.getSystemClassLoader( ) 方法获取到ApplicationClassLoader。 也可以认为BootStarpClassLoader只负责加载Java程序的核心类库自定义的加载器太low了不配“高端”加载器出手帮忙另外一方面BootStarpClassLoader是使用C和C进行编写的自热而然的就获取不到它的对象了。 public class ClassLoaderTest {public static void main(String[] args) {//获取系统类加载器ClassLoader systemClassLoader ClassLoader.getSystemClassLoader();System.out.println(systemClassLoader);//sun.misc.Launcher$AppClassLoader18b4aac2//获取其上层扩展类加载器ClassLoader extClassLoader systemClassLoader.getParent();System.out.println(extClassLoader);//sun.misc.Launcher$ExtClassLoader1540e19d//获取其上层获取不到引导类加载器ClassLoader bootstrapClassLoader extClassLoader.getParent();System.out.println(bootstrapClassLoader);//null//对于用户自定义类来说默认使用系统类加载器进行加载ClassLoader classLoader ClassLoaderTest.class.getClassLoader();System.out.println(classLoader);//sun.misc.Launcher$AppClassLoader18b4aac2//String类使用引导类加载器进行加载的。--- Java的核心类库都是使用引导类加载器进行加载的。ClassLoader classLoader1 String.class.getClassLoader();System.out.println(classLoader1);//null}
} 引导类、扩展类、系统类加载器的使用及演示 引导类加载器 在上面我们看到从最底层的systemClassLoader系统类加载器调用 getParent( )方法会调用到它上层的一个扩展类加载器和应用类加载器对象这些两个类加载器对象也都需要加载。都是通过BootStarpClassLoader引导类加载器进行加载的所以也就把BootStarpClassLoader、ExtClassLoader、ApplicationClassLoader都认为是系统核心类库。 扩展类加载器扩展类加载器扩展类加载器扩展类加载器扩展类加载器扩展类加载器扩展类加载器扩展类加载器扩展类加载器扩展类加载器 应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器应用程序类加载器 自定义类加载器自定义类加载器自定义类加载器自定义类加载器自定义类加载器 自定义加载器 package com.atguigu.java1;import java.io.FileNotFoundException;/*** 自定义用户类加载器* author shkstart* create 2019 下午 12:21*/
public class CustomClassLoader extends ClassLoader {Overrideprotected Class? findClass(String name) throws ClassNotFoundException {try {byte[] result getClassFromCustomPath(name);if(result null){throw new FileNotFoundException();}else{return defineClass(name,result,0,result.length);}} catch (FileNotFoundException e) {e.printStackTrace();}throw new ClassNotFoundException(name);}private byte[] getClassFromCustomPath(String name){//从自定义路径中加载指定类:细节略//如果指定路径的字节码文件进行了加密则需要在此方法中进行解密操作。return null;}public static void main(String[] args) {CustomClassLoader customClassLoader new CustomClassLoader();try {Class? clazz Class.forName(One,true,customClassLoader);Object obj clazz.newInstance();System.out.println(obj.getClass().getClassLoader());} catch (Exception e) {e.printStackTrace();}}
}package com.atguigu.java1;/*** author shkstart* create 2020 上午 10:59*/
public class ClassLoaderTest2 {public static void main(String[] args) {try {//1.获取引导类加载器 获取不到 nullClassLoader classLoader Class.forName(java.lang.String).getClassLoader();System.out.println(classLoader);//2.获取系统类加载器 sun.misc.Launcher$AppClassLoader18b4aac2ClassLoader classLoader1 Thread.currentThread().getContextClassLoader();System.out.println(classLoader1);//3.获取扩展类加载器 sun.misc.Launcher$ExtClassLoader1b6d3586ClassLoader classLoader2 ClassLoader.getSystemClassLoader().getParent();System.out.println(classLoader2);} catch (ClassNotFoundException e) {e.printStackTrace();}}
}