【问题标题】:Blocking threads using javassist in web app在 Web 应用程序中使用 javassist 阻塞线程
【发布时间】:2015-12-16 13:45:19
【问题描述】:

看看下面的线程转储,有人可以帮我解释一下到底发生了什么。这是一个在 Tomcat 7 上运行的 Web 应用程序,我们发现有些请求没有得到响应:

"ajp-bio-8012-exec-161" daemon prio=10 tid=0x00007fe170603000 nid=0x344f runnable [0x00007fe174fae000]
   java.lang.Thread.State: RUNNABLE
    at java.security.AccessController.doPrivileged(Native Method)
    at java.io.FilePermission.init(FilePermission.java:209)
    at java.io.FilePermission.<init>(FilePermission.java:285)
    at java.lang.SecurityManager.checkRead(SecurityManager.java:888)
    at java.io.File.exists(File.java:808)
    at sun.misc.URLClassPath$FileLoader.getResource(URLClassPath.java:1080)
    at sun.misc.URLClassPath$FileLoader.findResource(URLClassPath.java:1047)
    at sun.misc.URLClassPath.findResource(URLClassPath.java:176)
    at java.net.URLClassLoader$2.run(URLClassLoader.java:551)
    at java.net.URLClassLoader$2.run(URLClassLoader.java:549)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findResource(URLClassLoader.java:548)
    at java.lang.ClassLoader.getResource(ClassLoader.java:1147)
    at java.lang.ClassLoader.getResource(ClassLoader.java:1142)
    at org.apache.catalina.loader.WebappClassLoader.getResource(WebappClassLoader.java:1445)
    at java.lang.Class.getResource(Class.java:2142)
    at javassist.ClassClassPath.find(ClassClassPath.java:84)
    at javassist.ClassPoolTail.find(ClassPoolTail.java:317)
    at javassist.ClassPool.find(ClassPool.java:495)
    at javassist.ClassPool.createCtClass(ClassPool.java:479)
    at javassist.ClassPool.get0(ClassPool.java:445)
    - locked <0x00000000db6cdb48> (a javassist.ClassPool)
    at javassist.ClassPool.get(ClassPool.java:414)
    at javassist.compiler.MemberResolver.lookupClass0(MemberResolver.java:425)
    at javassist.compiler.MemberResolver.lookupClass(MemberResolver.java:389)
    at javassist.compiler.MemberResolver.lookupClassByJvmName(MemberResolver.java:310)
    at javassist.compiler.MemberResolver.lookupClass(MemberResolver.java:327)
    at javassist.compiler.MemberResolver.lookupClass(MemberResolver.java:314)
    at javassist.compiler.Javac.compileField(Javac.java:122)
    at javassist.compiler.Javac.compile(Javac.java:91)
    at javassist.CtField.make(CtField.java:163)
    at com.mycompany.validation.util.BeanGenerator.addProperty(BeanGenerator.java:157)
    ...
    at java.lang.Thread.run(Thread.java:745)


"ajp-bio-8012-exec-12" daemon prio=10 tid=0x0000000000c49800 nid=0x3d99 waiting for monitor entry [0x00007fe1756b7000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at javassist.ClassPool.get0(ClassPool.java:432)
    - waiting to lock <0x00000000db6cdb48> (a javassist.ClassPool)
    at javassist.ClassPool.get(ClassPool.java:414)
    at javassist.compiler.MemberResolver.lookupClass0(MemberResolver.java:425)
    at javassist.compiler.MemberResolver.lookupClass(MemberResolver.java:389)
    at javassist.compiler.MemberResolver.lookupClassByJvmName(MemberResolver.java:310)
    at javassist.compiler.MemberResolver.lookupClass(MemberResolver.java:327)
    at javassist.compiler.MemberResolver.lookupClass(MemberResolver.java:314)
    at javassist.compiler.Javac.compileField(Javac.java:122)
    at javassist.compiler.Javac.compile(Javac.java:91)
    at javassist.CtField.make(CtField.java:163)
    at com.mycompany.validation.util.BeanGenerator.addProperty(BeanGenerator.java:157)
    ...
    at java.lang.Thread.run(Thread.java:745)



"ajp-bio-8012-exec-5" daemon prio=10 tid=0x0000000001603800 nid=0x7c77 waiting for monitor entry [0x00007fe174aaa000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at javassist.ClassPool.makeClass(ClassPool.java:621)
    - waiting to lock <0x00000000db6cdb48> (a javassist.ClassPool)
    at javassist.ClassPool.makeClass(ClassPool.java:606)
    at com.mycompany.validation.util.BeanGenerator.init(BeanGenerator.java:334)
    ...
    at java.lang.Thread.run(Thread.java:745)    

我不是线程转储方面的专家,我只是想知道如何解决这个问题。

第一个线程是否锁定了其他两个请求线程正在等待解锁的对象(ClassPool)?为什么会被锁定?我必须同步吗?如何同步?

感谢任何提示!

【问题讨论】:

    标签: java multithreading tomcat javassist thread-dump


    【解决方案1】:

    您的应用程序中有一个 ClassPool,其监视器 ID 为 0x00000000db6cdb48。

    如果看到 ClassPool.get0 的方法签名:

    protected synchronized CtClass get0(String classname, boolean useCache)
    

    所以它是同步的。我想您只是使用了 ClassPool.getDefault()。你必须知道这个方法返回一个实例,所以你所有的调用都会同步。

    为每个线程创建一个新池(以new ClassPool(ClassPool.getDefault())为例)然后就可以了。

    除此之外,您可能会检查您的安全经理,为什么需要这么长时间。

    【讨论】:

    猜你喜欢
    • 2012-06-26
    • 2012-10-22
    • 2022-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多