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时,把点变为一个--写完 ...
随机推荐
- PCI、PCI-x,PCI-E兼容以及他们之间的区别详细图解
一.PCI PCI接口分为32bit和64bit两种,32bit就是一般台式机使用的普通的pci接口(图一.图三),64bit接口比32bit接口长一些一般只出现在服务器上(图四.图五).32bit和 ...
- Rplot
#!/usr/bin/Rscriptlibrary(ggplot2) cf = read.table(file = 'result_sort.txt', header = TRUE, sep='\t' ...
- openStack nova nova valid hosts 优化
scheduler_default_filters=AllHostsFilterallow_resize_to_same_host=Trueallow_migrate_to_same_host=Tru ...
- 黑暗之光 Day3
1. 滚动窗口 Scroll View. GameObject itemGo = NGUITools.AddChild(grid.gameObject, skillItemPrefab); grid. ...
- MyBatis 学习记录4 MyBatis的一级缓存
主题 分享记录一下MyBatis的一级缓存相关的学习. Demo public static void firstLevelCache() { init("mybatis-config.xm ...
- python:一个轻松的递归逻辑
#递归 age = 10 def dig(n): global age#函数dig引用全局变量age age += 2 n -= 1 if n != 1:#如果满足条件,则调用本身 dig(n) di ...
- Jquery.Ajax的使用方法
1.Get $('.manager_republish.notVIP').click(function () { $.ajax({ async: false, type: "get" ...
- ElasticSearch如何新增字段
/index/type/_mapping post { "properties": { "zy_renwu_pingjia": { "type&qu ...
- WCF配置多个终节点
配置多个终节点的意义(自己理解):一个服务可以有多个终节点,网上也经常有人说终节点才是服务的真正的接口,的确如此,当我们为一个服务配置多个终节点时,就表明这个服务可以被以不同的方式访问(不同的绑定等等 ...
- 前端开发之JavaScript HTML DOM实战篇
实战案例一: “灯泡发光” <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...