JVM

coding

如果需要热部署,使用“双亲委派”是不行的,如何打破“双亲委派”呢~

一. 源代码

“双亲委派”源代码如下(ClassLoader.java):

public Class<?> loadClass(String name) throws ClassNotFoundException {

return loadClass(name, false);

}

protected Class<?> loadClass(String name, boolean resolve)

throws ClassNotFoundException

{

synchronized (getClassLoadingLock(name)) {

// First, check if the class has already been loaded

Class<?> c = findLoadedClass(name);

if (c == null) {

long t0 = System.nanoTime();

try {

if (parent != null) {

c = parent.loadClass(name, false);

} else {

c = findBootstrapClassOrNull(name);

}

} catch (ClassNotFoundException e) {

// ClassNotFoundException thrown if class not found

// from the non-null parent class loader

}

if (c == null) {

// If still not found, then invoke findClass in order

// to find the class.

long t1 = System.nanoTime();

c = findClass(name);

// this is the defining class loader; record the stats

sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);

sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);

sun.misc.PerfCounter.getFindClasses().increment();

}

}

if (resolve) {

resolveClass(c);

}

return c;

}

}

二. 模拟热加载

public class Hello {

public Hello() {

}

public void test(){

System.out.println(System.currentTimeMillis() + " => hello world");

}

}

public class MyClassLoader extends ClassLoader{

public static void main(String[] args) throws Exception {

MyClassLoader m = new MyClassLoader();

Class clazz = m.loadClass("com.test.Hello");

clazz.getDeclaredMethod("test").invoke(clazz.getDeclaredConstructor().newInstance());

while (true){

TimeUnit.SECONDS.sleep(5);

m = new MyClassLoader();

clazz = m.loadClass("com.test.Hello");

clazz.getDeclaredMethod("test").invoke(clazz.getDeclaredConstructor().newInstance());

}

}

@Override

public Class<?> loadClass(String name) throws ClassNotFoundException {

String path = "D:/project/java/test/javaTest/target/classes/" + name.replace('.', '/') + ".class";

File f = new File(path);

if(!f.exists()) {

return super.loadClass(name);

}

try {

InputStream is = new FileInputStream(f);

byte[] b = new byte[is.available()];

is.read(b);

return defineClass(name, b, 0, b.length);

} catch (IOException e) {

e.printStackTrace();

}

return null;

}

}

运行结果:

1613700414784 => hello world

1613700419786 => hello world

1613700424787 => hello world


修改 Hello.java, 然后编译

public class Hello {

public Hello() {

}

public void test(){

System.out.println(System.currentTimeMillis() + " => hello world123");

}

}

运行结果:

1613700414784 => hello world

1613700419786 => hello world

1613700424787 => hello world

1613700429788 => hello world

1613700434789 => hello world

1613700439789 => hello world

1613700444789 => hello world

1613700449790 => hello world123

1613700454790 => hello world123

以上是 JVM 的全部内容, 来源链接: utcz.com/z/509772.html

回到顶部