- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我编写了两个自定义类加载器来动态加载代码。
第一个从 Jar 中加载代码:
package com.customweb.build.bean.include;
import java.net.URL;
import java.net.URLClassLoader;
import com.customweb.build.process.ILeafClassLoader;
public class JarClassLoader extends URLClassLoader implements ILeafClassLoader {
public JarClassLoader(URL[] urls, ClassLoader parent) {
super(urls, parent);
}
@Override
public Class<?> findClassWithoutCycles(String name) throws ClassNotFoundException {
Class<?> c = findLoadedClass(name);
if (c != null) {
return c;
}
return findClass(name);
}
@Override
protected Class<?> findClass(String qualifiedClassName) throws ClassNotFoundException {
synchronized (this.getParent()) {
synchronized (this) {
return super.findClass(qualifiedClassName);
}
}
}
@Override
public URL findResourceWithoutCycles(String name) {
return super.findResource(name);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
synchronized (this.getParent()) {
synchronized (this) {
return super.loadClass(name);
}
}
}
}
另一个类加载器采用多个类加载器以允许访问其他类加载器的类。在第一个初始化期间,我将此类加载器的一个实例设置为父级。为了打破循环,我使用方法“findClassWithoutCycles”。
package com.customweb.build.process;
import java.net.URL;
import java.security.SecureClassLoader;
import java.util.ArrayList;
import java.util.List;
public class MultiClassLoader extends SecureClassLoader {
private final List<ClassLoader> classLoaders = new ArrayList<ClassLoader>();
public MultiClassLoader(ClassLoader parent) {
super(parent);
}
public void addClassLoader(ClassLoader loader) {
this.classLoaders.add(loader);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
for (ClassLoader loader : classLoaders) {
try {
if (loader instanceof ILeafClassLoader) {
return ((ILeafClassLoader) loader).findClassWithoutCycles(name);
} else {
return loader.loadClass(name);
}
} catch (ClassNotFoundException e) {
// Ignore it, we try the next class loader.
}
}
throw new ClassNotFoundException(name);
}
@Override
protected URL findResource(String name) {
for (ClassLoader loader : classLoaders) {
URL url = null;
if (loader instanceof ILeafClassLoader) {
url = ((ILeafClassLoader) loader).findResourceWithoutCycles(name);
} else {
url = loader.getResource(name);
}
if (url != null) {
return url;
}
}
return null;
}
}
但是当我使用此类加载器时,大多数时候我都会遇到死锁。我已经经过这里的线程转储: http://pastebin.com/6wZKv4Y0
由于 Java ClassLoader 在某些方法中通过在 $this 上同步来阻塞线程,我尝试先在 MultiClassLoader 上同步,然后在 JarClassLoader 上同步。当获取锁的顺序相同时,这应该可以防止任何死锁。但似乎在 native 类加载例程的某个地方获取了对类加载器的锁定。我得出这个结论是因为线程“pool-2-thread-8”被锁定在对象“0x00000007b0f7f710”上。但是在日志中我看不到这个锁是什么时候被哪个线程获取的。
如何找出哪个线程在类加载器上进行同步?
编辑:我通过在调用 MultiClassLoader 的 loadClass 之前同步所有类加载器来解决这个问题。
最佳答案
JVM 在调用 loadClass 之前获取 ClassLoader 上的锁。如果通过您的 JarClassLoader 之一加载的类引用另一个类并且 JVM 尝试解析该引用,则会发生这种情况。它将直接转到创建该类的 ClassLoader,锁定它并调用 loadClass。但是随后您试图在再次锁定 JarClassLoader 之前锁定父加载器。所以这两个锁的顺序是行不通的。
但是我看不出这两个锁中任何一个的原因,因为您不访问任何需要同步的资源。 URLClassLoader 的继承内部状态由其实现本身维护。
但是,如果您想向需要同步的类添加更多状态,您应该使用不同的机制来锁定 ClassLoader 实例。
http://docs.oracle.com/javase/7/docs/technotes/guides/lang/cl-mt.html说
If you have a custom class loader with a risk of deadlocking, with the Java SE 7 release, you can avoid deadlocks by following these rules:
Ensure that your custom class loader is multithread safe for concurrent class loading.
a. Decide upon an internal locking scheme. For example, java.lang.ClassLoader uses a locking scheme based on the requested class name.
b. Remove all synchronization on the class loader object lock alone.
c. Ensure that critical sections are safe for multiple threads loading different classes.
In your custom class loader's static initializer, invoke java.lang.ClassLoader's static method registerAsParallelCapable(). This registration indicates that all instances of your custom class loader are multithread safe.
Check that all class loader classes that this custom class loader extends also invoke the registerAsParallelCapable() method in their class initializers. Ensure that they are multithread safe for concurrent class loading.
If your custom class loader overrides only findClass(String), you do not need further changes. This is the recommended mechanism to create a custom class loader.
关于类加载器中的 Java 死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18640996/
一、公平锁和非公平锁 1.1、公平锁和非公平锁的概述 公平锁:指多个线程按照申请锁的顺序来获取锁。 非公平锁:指在多线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取到锁
阅读目录 1、简介 2、分类 3、全局锁 4、表级锁 5、表锁 6、元数据锁
因此,在我编写的程序中,我有三个函数,为了简单起见,我们将它们称为 A、B 和 C。每个函数都需要访问资源X才能工作。 限制是A和B不允许同时运行并且必须适当同步。但是,C 可以与 A 或 B 同时运
我听说过这些与并发编程相关的词,但是锁、互斥量和信号量之间有什么区别? 最佳答案 锁只允许一个线程进入被锁定的部分,并且该锁不与任何其他进程共享。 互斥锁与锁相同,但它可以是系统范围的(由多个进程共享
这个问题已经有答案了: What is an efficient way to implement a singleton pattern in Java? [closed] (29 个回答) 已关闭
这个问题已经有答案了: What is an efficient way to implement a singleton pattern in Java? [closed] (29 个回答) 已关闭
我对标题中的主题有几个问题。首先,假设我们使用 JDBC,并且有 2 个事务 T1 和 T2。在 T1 中,我们在一个特定的行上执行 select 语句。然后我们对该行执行更新。在事务 T2 中,我们
我希望我的函数只运行一次。这意味着如果多个线程同时调用它,该函数将阻塞所有线程,只允许它运行。 最佳答案 听起来您希望存储过程进行同步。为什么不直接将同步放在应用程序本身中。 pthread_mute
if (runInDemoMode) { lock (this) { //Initalization of tables dCreator.create
我相信无论使用什么语言都可以考虑我的问题,但是为了有一些“ anchor ”,我将使用 Java 语言来描述它。 让我们考虑以下场景:我有一个扩展 Thread 的类 PickyHost 及其实例 p
我知道异步不是并行的,但我现在遇到了一个非常有趣的情况。 async function magic(){ /* some processing here */ await async () =
我们正在使用 Scala、Play 框架和 MongoDB(以 ReactiveMongo 作为我们的驱动程序)构建一个网络应用程序。应用程序架构是端到端的非阻塞。 在我们代码的某些部分,我们需要访问
我需要一个简单的锁,JavaME 超时(concurrent.lock 的反向移植需要完整的 Java 1.3)。 如果其他人已经为 JavaME 发布了经过测试的锁定代码,我宁愿使用它。 锁定是出了
根据 boost : To access the object, a weak_ptr can be converted to a shared_ptr using the shared_ptr co
关于 Mutex 和 Critical 部分之间的区别存在一个问题,但它也不处理 Locks。 所以我想知道临界区是否可以用于进程之间的线程同步。 还有信号状态和非信号状态的含义 最佳答案 在 Win
锁 最为常见的应用就是 高并发的情况下,库存的控制。本次只做简单的单机锁介绍。 直接看代码: 每请求一次库存-1. 假如库存1000,在1000个人请求之后,库存将变为0。
线程和进程 1、线程共享创建它的进程的地址空间,进程有自己的地址空间 2、线程可以访问进程所有的数据,线程可以相互访问 3、线程之间的数据是独立的 4、子进程复制线程的数据 5、子进程启动
**摘要:**细心的你也一定关注到,有的网址是https开头的,有的是http。https开头的网站前面,会有一把小锁。这是为什么呢? 本文分享自华为云社区《还不知道SSL证书已经是刚需了?赶快来了解
试图在 C 中实现一个非常简单的互斥锁(锁)我有点困惑。我知道互斥锁类似于二进制信号量,除了互斥锁还强制执行释放锁的线程的约束,必须是最近获得它的同一线程。我对如何跟踪所有权感到困惑? 这是我到目前为
在阅读了很多与上述主题相关的文章和答案之后,我仍然想知道 SQL Server 数据库引擎在以下示例中是如何工作的: 假设我们有一个名为 t3 的表: create table t3 (a int ,
我是一名优秀的程序员,十分优秀!