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时,把点变为一个--写完 ...
随机推荐
- Memory leak by misusing Autofac
Recently I’ve found out that we can easily cause a memory leaks in our .net application by improper ...
- 二、jenkins配置email(以腾讯企业qq为例)
废话不多说,直接上干货: 主要针对两个部分进行介绍: 1.jenkins内置的邮件功能: 2.Editable Email Notification插件的邮件功能: 低版本的jenkins有很多插件都 ...
- Delphi IOS class_addMethod
class_addMethod 学习FMX.Platform.iOS.pas文件的处理办法 d:\program files (x86)\embarcadero\studio\17.0\source\ ...
- 聊聊flutter的UI布局
UI布局多半是套路,熟悉套路的规则. Flutter的UI布局也有一套规则 center center可以让任何元素在屏幕中居中,既是水平居中又是垂直居中,如果想让元素从上而下排列要怎么办呢?那就得使 ...
- Redis AOF 全持久化
简介: Redis AOF 持久化,将每次接收到更改 redis 数据的操作都记录到一个 aof 文件,当服务器意外宕机或 redis 服务器非法关闭时,不会丢失数据. 可以做到数据安全化,但是性能会 ...
- flex 设置换行flex-wrap
flex 设置flex-wrap 换行 本来预想的正常情况下,代码应该如下: ul { width: 100%; display: flex; flex-wrap: wrap; li { ; widt ...
- pip 18.1 官方文档翻译
快速开始 从pypi上安装一个包 $ pip install SomePackage 查看安装的包里面包含什么文件 pip show --files SomePackage 查看已经安装的包里面哪些是 ...
- linux查看电脑硬件配置
1. 查看CPU cat /proc/cpuinfo 2. 查看内存 free -m 3. 查看硬盘分区 fdisk -l 4. 查看网卡信息或者ip地址 ifconfig 5. 查看详细的网卡工作模 ...
- java算法 第七届 蓝桥杯B组(题+答案) 10.压缩变换
10.压缩变换 (程序设计) 小明最近在研究压缩算法.他知道,压缩的时候如果能够使得数值很小,就能通过熵编码得到较高的压缩比.然而,要使数值很小是一个挑战. 最近,小明需要压缩一些正整数的序列,这些 ...
- lucene4
在lucene通过对应的API建立索引.在学习的过程中我们了解到lucene下面索引的建立与关系数据库有相似的地方. IndexReader.delete删除有两种删除的形式. 第三个改变Docume ...