我认为我发现了一种情况,即混合使用log4j a)直接和b)通过commons-logging导致某种类加载死锁.我不确定这种情况是否可行(JVM是否应该检测到这种情况?)以及如何处理它.
在我们的构建系统中,我们目前正在按顺序运行单元测试 - 为了使构建更快,我们显然可以改变它以并行运行我们的单元测试.但是,如果我们这样做,一些构建会遇到执行超时.在分析这种"悬挂构建"的线程转储时,我们发现自己处于不同的模块中,大多数时间都涉及不同的测试.但它总是归结为两个线程尝试初始化一个Logger:一个用Logger.getLogger(直接使用log4j),另一个用LogFactory.getLog(使用commons-logging).
所以我们在这个地方有一个线程(直接使用log4j的线程):
"pool-1-thread-3" prio=10 tid=0x00007f6528ca6000 nid=0x6f8f in Object.wait() [0x00007f64d9ca6000]
java.lang.Thread.State: RUNNABLE
at org.apache.log4j.LogManager.<clinit>(LogManager.java:82)
at org.apache.log4j.Logger.getLogger(Logger.java:117)
at de.is24.platform.contacts.domain.PhoneNumberFormat.<clinit>(PhoneNumberFormat.java:21)
Run Code Online (Sandbox Code Playgroud)
不幸的是,这是一个相当"拥挤"的路线:
Hierarchy h = new Hierarchy(new RootLogger((Level) Level.DEBUG));
Run Code Online (Sandbox Code Playgroud)
另一个线程(使用commons-logging)在这里等待:
"pool-1-thread-2" prio=10 tid=0x00007f6528bf9800 nid=0x6f8e in Object.wait() [0x00007f64d9da7000]
java.lang.Thread.State: RUNNABLE
at org.apache.log4j.Priority.<clinit>(Priority.java:45)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:171)
at org.apache.commons.logging.impl.Log4JLogger.class$(Log4JLogger.java:37)
at org.apache.commons.logging.impl.Log4JLogger.<clinit>(Log4JLogger.java:45)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.apache.commons.logging.impl.LogFactoryImpl.newInstance(LogFactoryImpl.java:529)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:235)
at org.apache.commons.logging.impl.LogFactoryImpl.getInstance(LogFactoryImpl.java:209)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:351)
Run Code Online (Sandbox Code Playgroud)
这很简单:
final static public Priority FATAL = …Run Code Online (Sandbox Code Playgroud) 有两种"部署"Java Lambda的方法:
由于执行我们简单的Lambda的环境需要很长时间才能"启动"(20-30秒),我想知道这两种方法是否比另一种"更快"还是可以进一步加速?