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时,把点变为一个--写完 ...
随机推荐
- Html 上手
<!-- ctrl + / 注释 ctrl + D 复制整行 html:超文本标记语言标记 标签 元素格式<标签名>标签内容</标签名>标签的写法标签的正确嵌套标签特性 ...
- 利用Linux系统生成随机密码的9种方法
Linux操作系统的一大优点是对于同样一件事情,你可以使用高达数百种方法来实现它.例如,你可以通过数十种方法来生成随机密码.本文将介绍生成随机密码的十种方法. 1. 使用SHA算法来加密日期,并输出结 ...
- python开发_function annotations
在看python的API的时候,发现了一个有趣的东东,即:python的方法(函数)注解(Function Annotation) 原文: 4.7.7. Function Annotations Fu ...
- .net Reactor之限指定设备使用
.net Reactor之license限指定设备使用 上一篇(https://www.cnblogs.com/s313139232/p/9908400.html)中记录了.net Reactor对d ...
- leetcode687
/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode ...
- django -- url (模版语言 {% url 'test1' param1=5 param2=6 %})
如果想让form表单提交的url是类似 action="/index-5-6.html" 这样的,可以在html模版语言中使用{% url 'test1' param1=5 par ...
- delphi IOS 后台状态保存
FormSaveState procedure TFrm.FormSaveState(Sender: TObject);begin end; http://stackoverflow.com/ques ...
- T-SQL 之 执行顺序
1.sql查询语句的处理步骤,代码清单 --查询组合字段 (5)select (5-2) distinct(5-3) top(<top_specification>)(5-1)<se ...
- [iOS]UIScrollView嵌套UITableView,超出屏幕的cell点击不了问题
最初我是用UIScrollView嵌套了一个UIView,然后UIView里面嵌套UITableView,这样cell 就会超出屏幕那一部分点击不了. 解决方法如下,UITableView拖出来,作为 ...
- 查看端口占用情况lsof,并关闭对应进程kill
lsof -n -P| grep ":<端口号>" | grep LISTEN #监听对应端口号的进程 lsof -i tcp:<端口号> #和对应端口号有 ...