Class Loading Deadlocks
By tomas.nilsson on Feb 28, 2010
Mattis keeps going strong, in this installment you get to learn everything you never you knew you may need to know about class loaders.
As I wrote in a previous post, the class loading mechanism in Java is very powerful. There are many advanced techniques you can use, and when used wrongly you can get into all sorts of trouble. But one of the sneakiest deadlocks you can run into when it comes to class loading doesn't require any home made class loaders or anything. All you need is classes depending on each other, and some bad luck.
First of all, here are some basic facts about class loading:
1) If a thread needs to use a class that is not yet loaded, it will try to load that class
2) If another thread is already loading the class, the first thread will wait for the other thread to finish the loading
3) During the loading of a class, one thing that happens is that the method of a class is being run
4) The method initializes all static fields, and runs any static blocks in the class.
Take the following class for example:
class Foo {
static Bar bar = new Bar();
static {
System.out.println("Loading Foo");
}
}
The first time a thread needs to use the Foo class, the class will be initialized. The method will run, creating a new Bar object and printing "Loading Foo"
But what happens if the Bar object has never been used before either? Well, then we will need to load that class as well, calling the Bar method as we go.
Can you start to see the potential problem here? A hint is in fact #2 above.
What if another thread is currently loading class Bar? The thread loading class Foo will have to wait for that thread to finish loading. But what happens if the method of class Bar tries to initialize a Foo object? That thread will have to wait for the first thread, and there we have the deadlock. Thread one is waiting for thread two to initialize class Bar, thread two is waiting for thread one to initialize class Foo.
All that is needed for a class loading deadlock is static cross dependencies between two classes (and a multi threaded environment):
class Foo {
static Bar b = new Bar();
}
class Bar {
static Foo f = new Foo();
}
If two threads cause these classes to be loaded at exactly the same time, we will have a deadlock.
So, how do you avoid this? Well, one way is of course to not have these circular (static) dependencies. On the other hand, it can be very hard to detect these, and sometimes your design may depend on it. What you can do in that case is to make sure that the classes are first loaded single threadedly, for example during an initialization phase of your application.
The following program shows this kind of deadlock. To help bad luck on the way, I added a one second sleep in the static block of the classes to trigger the unlucky timing. Notice that if you uncomment the "//Foo f = new Foo();" line in the main method, the class will be loaded single threadedly, and the program will terminate as it should.
public class ClassLoadingDeadlock {
// Start two threads. The first will instansiate a Foo object,
// the second one will instansiate a Bar object.
public static void main(String[] arg) {
// Uncomment next line to stop the deadlock
// Foo f = new Foo();
new Thread(new FooUser()).start();
new Thread(new BarUser()).start();
}
}
class FooUser implements Runnable {
public void run() {
System.out.println("FooUser causing class Foo to be loaded");
Foo f = new Foo();
System.out.println("FooUser done");
}
}
class BarUser implements Runnable {
public void run() {
System.out.println("BarUser causing class Bar to be loaded");
Bar b = new Bar();
System.out.println("BarUser done");
}
}
class Foo {
static {
// We are deadlock prone even without this sleep...
// The sleep just makes us more deterministic
try {
Thread.sleep(1000);
} catch(InterruptedException e) {}
}
static Bar b = new Bar();
}
class Bar {
static {
try {
Thread.sleep(1000);
} catch(InterruptedException e) {}
}
static Foo f = new Foo();
}
Class Loading Deadlocks的更多相关文章
- Java classes and class loading
JAVA类加载器概念与线程类加载器 http://www.cnblogs.com/pfxiong/p/4118445.html http://stackoverflow.com/questions/2 ...
- 步入angularjs directive(指令)--点击按钮加入loading状态
今天我终于鼓起勇气写自己的博客了,激动与害怕并存,希望大家能多多批评指导,如果能够帮助大家,也希望大家点个赞!! 用angularjs 工作也有段时间了,总体感觉最有挑战性的还是指令,因为没有指令的a ...
- 《动手实现一个网页加载进度loading》
loading随处可见,比如一个app经常会有下拉刷新,上拉加载的功能,在刷新和加载的过程中为了让用户感知到 load 的过程,我们会使用一些过渡动画来表达.最常见的比如"转圈圈" ...
- eclipse 突然 一直在loading descriptor for XXX (XXX为工程名)Cancel Requested
问题: eclipse 启动后,啥也不干,就一直在loading descriptor for XXX (XXX为工程名),,其他什么操作都不能操作. 如下图所示,保存文件也无法保存. 这个怎么办? ...
- linux使用wkhtmltopdf报错error while loading shared libraries:
官网提示 linux需要这些动态库.depends on: zlib, fontconfig, freetype, X11 libs (libX11, libXext, libXrender) 在li ...
- solr定时更新索引遇到的问题(SolrDataImportProperties Error loading DataImportScheduler properties java.lang.NullPointerException)
问题描述 报如下错误,很显然,问题原因:空指针异常: ERROR (localhost-startStop-1) [ ] o.a.s.h.d.s.SolrDataImportProperties ...
- python3: error while loading shared libraries: libpython3.5m.so.1.0: cannot open shared object file: No such file or directory
安装python3遇到报错: wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz ./configure --prefix=/u ...
- x01.os.21: print "Loading..."
Linux Inside 是中文版,值得下载一读. 先把目标设低点,开机进入后,在屏幕上打印“Loading..."即可.由于要在 bochs 中运行,首先就是安装 bochs.Oldlin ...
- 利用animation和text-shadow纯CSS实现loading点点点的效果
经常在网上看到loading状态时的点点点的动态效果,自己也用JS写了一个,思路是使用一个计数参数,然后在需要添加点的元素后面利用setInterval一个一个加点,当计数到3时,把点变为一个--写完 ...
随机推荐
- Oracle回收站使用全攻略
摘要:回收站(Recycle Bin)从原理上来说就是一个数据字典表,放置用户删除(drop)掉的数据库对象信息.用户进行删除操作的对象并没有被数据库删除,仍然会占用空间.除非是由于用户手工进行Pur ...
- dt转实体
public class DtConvertToList<T> where T : new() { /// <summary> /// 实体转换辅助类 /// </sum ...
- 0007-一套完整的CRUD_DEMO
好久没写了,一直在忙别的东西,但是想想,还是把之前的补充完整好了.给大家一个参考,也为自己留个备份. 首先写一个Html作为内容载体,主要结构如下 <div ui-view="navb ...
- OD 实验(十五) - 对一个程序的逆向
程序: 打开程序 出现一个 NAG 窗口 这是主界面 点击 Exit 程序出现 NAG 窗口,然后退出 用 PEiD 看一下 是用 VC++ 6.0 写的程序 逆向: 用 OD 载入程序 跑一下程序 ...
- GridControl 添加全选列
这里通过List对象绑定GridControl,且不用在GirdControl界面中添加任何列,实现CheckBox列的方法 1.列表中出现CheckBox列 非常简单,在绑定的List实体中,增加一 ...
- 关于PHP导出excel文件名乱码的问题
关于PHP导出excel文件名乱码的问题 对于中文的文件名使用,urlencode即可避免此问题 urlencode() 申请的urlencode()
- Android 4 学习(20):ActionBar
参考<Pro Android 4.0> ActionBar 11.0之后,ActionBar在Activity中默认存在,可以在代码中设置其显示与否: ActionBar actionBa ...
- Rhythmk 一步一步学 JAVA (17):Servlet 文件上传
1.环境 : JDK 1.6 , Tomcat 7.0 2.第三方类库: commons-fileupload-1.3.1.jar commons-io-2.4.jar 3.web.xml配置: &l ...
- leetcode703
class KthLargest { public: KthLargest(int k, vector<int> nums) { size = k; for(auto num:nums){ ...
- myBaits association的使用
转自:https://blog.csdn.net/victor_cindy1/article/details/50194879 >