Locked ownable synchronizers(转)
public class DeadLock {
public static void main(final String[] args) throws Exception {
final Object lock1 = new Object();
final Object lock2 = new Object();
Thread.currentThread().setName("main-thread");
final Thread r = new Thread("another-thread") {
@Override
public void run() {
try {
synchronized (lock2) {
Thread.sleep(20000);
synchronized (lock1) {
Thread.sleep(20000);
}
}
}
catch (final Exception e) {
e.printStackTrace();
}
}
};
r.start();
Thread.sleep(5000);
synchronized (lock1) {
Thread.sleep(20000);
synchronized (lock2) {
Thread.sleep(20000);
}
}
}
}
这段代码可能有点复杂,但原理不麻烦,就是描述了经典的加锁顺序问题。栈信息比较有趣,裁剪之后如下。
"another-thread" prio= tid=0x02b22400 nid=0x2250 waiting for monitor entry [0x0316f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at DeadLock$.run(DeadLock.java:)
- waiting to lock <0x22bc3f90> (a java.lang.Object)
- locked <0x22bc3f98> (a java.lang.Object) Locked ownable synchronizers:
- None
"main-thread" prio= tid=0x00868800 nid=0x2634 waiting for monitor entry [0x0098f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at DeadLock.main(DeadLock.java:)
- waiting to lock <0x22bc3f98> (a java.lang.Object)
- locked <0x22bc3f90> (a java.lang.Object) Locked ownable synchronizers:
- None
Found one Java-level deadlock:
=============================
"another-thread":
waiting to lock monitor 0x02ad433c (object 0x22bc3f90, a java.lang.Object),
which is held by "main-thread"
"main-thread":
waiting to lock monitor 0x02ad363c (object 0x22bc3f98, a java.lang.Object),
which is held by "another-thread" Java stack information for the threads listed above:
===================================================
"another-thread":
at DeadLock$.run(DeadLock.java:)
- waiting to lock <0x22bc3f90> (a java.lang.Object)
- locked <0x22bc3f98> (a java.lang.Object)
"main-thread":
at DeadLock.main(DeadLock.java:)
- waiting to lock <0x22bc3f98> (a java.lang.Object)
- locked <0x22bc3f90> (a java.lang.Object) Found deadlock.
主线程中提示了当前持有的锁和期望获取的锁,而新线程也存在类似的提示,只是获取锁的顺序不同。从栈信息可以看出,两个线程都处于BLOCKED状态。可能是源代码中的问题过于明显,导出的栈信息中给出了死锁的提示信息,实际项目的业务代码比样例要复杂,JVM可能做不到这么智能。这里的提示信息多多少少有点让我失望,在主线程栈信息的最后一部分没有输出当前持有锁的列表,很奇怪,不知道是不是和JDK的实现有关。
import java.security.SecureRandom;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.ReentrantLock; public class DeadLock {
private final ReentrantLock lock = new ReentrantLock();
private static final SecureRandom random = new SecureRandom(); public DeadLock() {
} public void runWork() { final ThreadPoolExecutor threadpool = new ThreadPoolExecutor(3, 3, 60L, TimeUnit.DAYS,
new SynchronousQueue<Runnable>(), new ThreadFactory() {
private final AtomicInteger counter = new AtomicInteger(1);
@Override
public Thread newThread(final Runnable r) {
return new Thread(r, "thread-sn-" + counter.getAndIncrement());
}
});
threadpool.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
Thread.currentThread().setName("main-thread");
for (int i = 0; i < 15; ++i) {
threadpool.submit(new Runnable() {
@Override
public void run() {
try { int timeout = 0;
while ((timeout = random.nextInt()) <= 0) {
}
timeout = timeout % 111;
Thread.sleep(timeout * 100L); lock.lock();
callLongTime(); }
catch (final Exception e) {
e.printStackTrace();
}
finally {
lock.unlock();
}
}
});
}
threadpool.shutdown();
} public static void main(final String[] args) throws Exception {
new DeadLock().runWork();
} static long callLongTime() {
System.out.println("thread name " + Thread.currentThread().getName());
long sum = 0;
for (long i = 0; i < 10000000000L; ++i) {
sum = sum ^ i + i;
}
return sum;
}
}
最后一个样例,写的比较复杂,但事情比较简单,线程之间的同步关键字换成了Java5提供的concurrent库中的重入锁。
"thread-sn-3" prio= tid=0x02de8400 nid=0x2688 runnable [0x0320f000]
java.lang.Thread.State: RUNNABLE
at DeadLock.callLongTime(DeadLock.java:)
at DeadLock$.run(DeadLock.java:)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:)
at java.util.concurrent.FutureTask.run(FutureTask.java:)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:)
at java.lang.Thread.run(Thread.java:) Locked ownable synchronizers:
- <0x22be1488> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
- <0x22be66d8> (a java.util.concurrent.ThreadPoolExecutor$Worker) "thread-sn-2" prio= tid=0x02de6c00 nid=0x218c waiting on condition [0x031bf000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x22be1488> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:)
at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:)
at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:)
at DeadLock$.run(DeadLock.java:)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:)
at java.util.concurrent.FutureTask.run(FutureTask.java:)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:)
at java.lang.Thread.run(Thread.java:) Locked ownable synchronizers:
- <0x22be64e0> (a java.util.concurrent.ThreadPoolExecutor$Worker)
栈信息比较有趣,JVM在每个线程线的最后部分输出了当前线程持有的锁对象,类型和地址。从上述的信息中可以找到,当前处于运行状态的线程持有了一个地址为0x22be1488的锁,而这个锁正是其它线程等待获取的锁对象。
http://blog.csdn.net/jackie_xiaonan/article/details/8577785
Locked ownable synchronizers(转)的更多相关文章
- 检查死锁与Locked ownable synchronizers(转载)
通过jstack可快速检查线程的死锁信息,用法如下: # 获取JVM ID(JAVA 进程ID),通过参数lv可以获取更详细的JAVA方法调用信息 jps -lv # 得到JVM ID后,执行jsta ...
- 《深入理解Java虚拟机》虚拟机性能监控与故障处理工具
上节学习回顾 从课本章节划分,<垃圾收集器>和<内存分配策略>这两篇随笔同属一章节,主要是从理论+实验的手段来讲解JVM的内存处理机制.好让我们对JVM运行机制有一个良好的概念 ...
- jvm系列(四):jvm调优-命令大全(jps jstat jmap jhat jstack jinfo)
文章同步发布于github博客地址,阅读效果更佳,欢迎品尝 运用jvm自带的命令可以方便的在生产监控和打印堆栈的日志信息帮忙我们来定位问题!虽然jvm调优成熟的工具已经有很多:jconsole.大名鼎 ...
- Java线程问题分析定位
Java线程问题分析定位 分析步骤: 1.使用top命令查看系统资源占用情况,发现Java进程占用大量CPU资源,PID为11572: 2.显示进程详细列表命令:ps -mp 11572 -o THR ...
- 一则JVM memory leak解决的过程
起因是我们的集群应用(3台机器)新版本测试过程中,一般的JVM内存占用 都在1G左右, 但在运行了一段时间后,慢慢升到了4G, 这是一个明显不正常的现象. 定位 过程: 1.先在该机器上按照步骤尝试重 ...
- Java多线程之Runable与Thread
Java多线程是Java开发中的基础内容,但是涉及到高并发就有很深的研究可做了. 最近看了下<Java并发实战>,发先有些地方,虽然可以理解,但是自己在应用中很难下手. 所以还是先回顾一下 ...
- 不正确使用WeakHashMap引起的卡死
公司的jenkins今天出了一点问题,起来以后,总是处于等待状态,所有的任务无法正常加载.登陆界面也出不了.而且cpu占用率100% 把线程导出来,看到: “Loading job NMS_Patch ...
- [已解决] java.net.InetAddress.getHostName() 阻塞问题
在学习java nio的过程中发现某些情况下使用该方法会导致程序阻塞,(情况:服务器,Linux:客户端,WIN10) java.net.InetAddress.getHostName() 阻塞情况如 ...
- 怎样分析java线程堆栈日志
注: 该文章的原文是由 Tae Jin Gu 编写,原文地址为 How to Analyze Java Thread Dumps 当有障碍,或者是一个基于 JAVA 的 WEB 应用运行的比预期慢的时 ...
随机推荐
- Shell printf 命令
Shell printf 命令 printf 命令模仿 C 程序库(library)里的 printf() 程序. 标准所定义,因此使用printf的脚本比使用echo移植性好. printf 使用引 ...
- 蜘蛛侠天堂,打死我mac键盘
今天是周末,在我租住的房间,以一个离奇事件. 一个蜘蛛侠天堂,趴在我的假期车窗玻璃,爬下沿着玻璃.特别糟糕.可以飞檐走壁. 可惜体力不支,摔死在我的mac键盘上. 有图有视频. 视频链接:http:/ ...
- Java Thread.join()详解(转)
(1)join方法是可以中断的(2)在线程joiner在另一个线程t上调用t.join(),线程joiner将被挂起,直到线程t结束(即t.isAlive()返回为false)才恢复 package ...
- eclipse中我要同时看两个console
eclipse中我要同时看两个console 有一个按钮“New Console View”,可以让你再建一个Console,还有一个按钮“Display Selected Console”,可以在两 ...
- mysql 数据库备份ubuntu
安装 1 sudo apt-get update 2. sudo apt-get install mysql-server 3 sudo apt-get install mysql-client 4 ...
- 伤不起的戴尔台式机XPS8700脆弱的蓝牙
http://en.community.dell.com/support-forums/desktop/f/3514/t/19520747.aspx 1.报价仅仅包含主机,并且不带音响(speaker ...
- ARM架构和编程-4
ARM中断异常处理: ARM系统中止品种:按中断处理降序排列优先级:重置.数据访问中止.高速中断请求.外部中断请求.预取中止.令.软件中断. ARM体系中的异常中断向量表: 0x0 复位 0x4 没有 ...
- 【Nginx】启动过程
从应用程序的启动过程中main功能开始跟踪. 解析命令行參数并保存到ngx_cycle_t结构体中,在ngx_process_options函数中将保存配置文件路径. 调用ngx_add_inheri ...
- Eclipse中的Maven项目报Unbound classpath variable错误
今天更新了最新版的Eclipse luna 4.4版本号,svn更新了项目后,系统一直报错,经查看在Problems窗体中发现一堆错误.提演示样例如以下: Unbound classpath ...
- jquery关于表格隐藏和显示问题
1. 关于指定表格指定列隐藏显示 $(":checkbox[name*=month]").each(function(){ if(!$(this).attr("check ...