Java如何使用线程解决死锁?
在Java编程中,如何使用线程解决死锁?
以下示例演示如何使用线程的概念解决死锁问题。
// from W w w .Y I I b AI.c o M
package com.yiibai;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
public class SolvingDeadlock extends ReentrantLock {
private static List deadlockLocksRegistry = new ArrayList();
private static synchronized void registerLock(SolvingDeadlock ddl) {
if (!deadlockLocksRegistry.contains(ddl))
deadlockLocksRegistry.add(ddl);
}
private static synchronized void unregisterLock(SolvingDeadlock ddl) {
if (deadlockLocksRegistry.contains(ddl))
deadlockLocksRegistry.remove(ddl);
}
private List hardwaitingThreads = new ArrayList();
private static synchronized void markAsHardwait(List l, Thread t) {
if (!l.contains(t))
l.add(t);
}
private static synchronized void freeIfHardwait(List l, Thread t) {
if (l.contains(t))
l.remove(t);
}
private static Iterator getAllLocksOwned(Thread t) {
SolvingDeadlock current;
ArrayList results = new ArrayList();
Iterator itr = deadlockLocksRegistry.iterator();
while (itr.hasNext()) {
current = (SolvingDeadlock) itr.next();
if (current.getOwner() == t)
results.add(current);
}
return results.iterator();
}
private static Iterator getAllThreadsHardwaiting(SolvingDeadlock l) {
return l.hardwaitingThreads.iterator();
}
private static synchronized boolean canThreadWaitOnLock(Thread t, SolvingDeadlock l) {
Iterator locksOwned = getAllLocksOwned(t);
while (locksOwned.hasNext()) {
SolvingDeadlock current = (SolvingDeadlock) locksOwned.next();
if (current == l)
return false;
Iterator waitingThreads = getAllThreadsHardwaiting(current);
while (waitingThreads.hasNext()) {
Thread otherthread = (Thread) waitingThreads.next();
if (!canThreadWaitOnLock(otherthread, l)) {
return false;
}
}
}
return true;
}
public SolvingDeadlock() {
this(false, false);
}
public SolvingDeadlock(boolean fair) {
this(fair, false);
}
private boolean debugging;
public SolvingDeadlock(boolean fair, boolean debug) {
super(fair);
debugging = debug;
registerLock(this);
}
public void lock() {
if (isHeldByCurrentThread()) {
if (debugging)
System.out.println("Already Own Lock");
super.lock();
freeIfHardwait(hardwaitingThreads, Thread.currentThread());
return;
}
markAsHardwait(hardwaitingThreads, Thread.currentThread());
if (canThreadWaitOnLock(Thread.currentThread(), this)) {
if (debugging)
System.out.println("Waiting For Lock");
super.lock();
freeIfHardwait(hardwaitingThreads, Thread.currentThread());
if (debugging)
System.out.println("Got New Lock");
} else {
throw new DeadlockDetectedException("DEADLOCK");
}
}
public void lockInterruptibly() throws InterruptedException {
lock();
}
public class DeadlockDetectingCondition implements Condition {
Condition embedded;
protected DeadlockDetectingCondition(ReentrantLock lock, Condition embedded) {
this.embedded = embedded;
}
public void await() throws InterruptedException {
try {
markAsHardwait(hardwaitingThreads, Thread.currentThread());
embedded.await();
} finally {
freeIfHardwait(hardwaitingThreads, Thread.currentThread());
}
}
public void awaitUninterruptibly() {
markAsHardwait(hardwaitingThreads, Thread.currentThread());
embedded.awaitUninterruptibly();
freeIfHardwait(hardwaitingThreads, Thread.currentThread());
}
public long awaitNanos(long nanosTimeout) throws InterruptedException {
try {
markAsHardwait(hardwaitingThreads, Thread.currentThread());
return embedded.awaitNanos(nanosTimeout);
} finally {
freeIfHardwait(hardwaitingThreads, Thread.currentThread());
}
}
public boolean await(long time, TimeUnit unit) throws InterruptedException {
try {
markAsHardwait(hardwaitingThreads, Thread.currentThread());
return embedded.await(time, unit);
} finally {
freeIfHardwait(hardwaitingThreads, Thread.currentThread());
}
}
public boolean awaitUntil(Date deadline) throws InterruptedException {
try {
markAsHardwait(hardwaitingThreads, Thread.currentThread());
return embedded.awaitUntil(deadline);
} finally {
freeIfHardwait(hardwaitingThreads, Thread.currentThread());
}
}
public void signal() {
embedded.signal();
}
public void signalAll() {
embedded.signalAll();
}
}
public Condition newCondition() {
return new DeadlockDetectingCondition(this, super.newCondition());
}
private static Lock a = new SolvingDeadlock(false, true);
private static Lock b = new SolvingDeadlock(false, true);
private static Lock c = new SolvingDeadlock(false, true);
private static Condition wa = a.newCondition();
private static Condition wb = b.newCondition();
private static Condition wc = c.newCondition();
private static void delaySeconds(int seconds) {
try {
Thread.sleep(seconds * 1000);
} catch (InterruptedException ex) {
}
}
private static void awaitSeconds(Condition c, int seconds) {
try {
c.await(seconds, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
}
}
private static void testOne() {
new Thread(new Runnable() {
public void run() {
System.out.println("thread one grab a");
a.lock();
delaySeconds(2);
System.out.println("thread one grab b");
b.lock();
delaySeconds(2);
a.unlock();
b.unlock();
}
}).start();
new Thread(new Runnable() {
public void run() {
System.out.println("thread two grab b");
b.lock();
delaySeconds(2);
System.out.println("thread two grab a");
a.lock();
delaySeconds(2);
a.unlock();
b.unlock();
}
}).start();
}
private static void testTwo() {
new Thread(new Runnable() {
public void run() {
System.out.println("thread one grab a");
a.lock();
delaySeconds(2);
System.out.println("thread one grab b");
b.lock();
delaySeconds(10);
a.unlock();
b.unlock();
}
}).start();
new Thread(new Runnable() {
public void run() {
System.out.println("thread two grab b");
b.lock();
delaySeconds(2);
System.out.println("thread two grab c");
c.lock();
delaySeconds(10);
b.unlock();
c.unlock();
}
}).start();
new Thread(new Runnable() {
public void run() {
System.out.println("thread three grab c");
c.lock();
delaySeconds(4);
System.out.println("thread three grab a");
a.lock();
delaySeconds(10);
c.unlock();
a.unlock();
}
}).start();
}
private static void testThree() {
new Thread(new Runnable() {
public void run() {
System.out.println("thread one grab b");
b.lock();
System.out.println("thread one grab a");
a.lock();
delaySeconds(2);
System.out.println("thread one waits on b");
awaitSeconds(wb, 10);
a.unlock();
b.unlock();
}
}).start();
new Thread(new Runnable() {
public void run() {
delaySeconds(1);
System.out.println("thread two grab b");
b.lock();
System.out.println("thread two grab a");
a.lock();
delaySeconds(10);
b.unlock();
c.unlock();
}
}).start();
}
public static void main(String args[]) {
int test = 1;
if (args.length > 0)
test = Integer.parseInt(args[0]);
switch (test) {
case 1:
testOne();
break;
case 2:
testTwo();
break;
case 3:
testThree();
break;
default:
System.err.println("usage: java DeadlockDetectingLock [ test# ]");
}
delaySeconds(60);
System.out.println("--- End Program ---");
System.exit(0);
}
}
class DeadlockDetectedException extends RuntimeException {
public DeadlockDetectedException(String s) {
super(s);
}
}
上述代码示例将产生以下结果 -
thread one grab a
Waiting For Lock
thread two grab b
Got New Lock
Waiting For Lock
Got New Lock
thread one grab b
Exception in thread "Thread-1" thread two grab a
Waiting For Lock
com.yiibai.DeadlockDetectedException: DEADLOCK
at com.yiibai.SolvingDeadlock.lock(SolvingDeadlock.java:102)
at com.yiibai.SolvingDeadlock$2.run(SolvingDeadlock.java:213)
at java.lang.Thread.run(Unknown Source)
Java如何使用线程解决死锁?的更多相关文章
- Java如何使用线程解决生产者消费者问题?
在Java编程中,如何使用线程解决生产者消费者问题? 以下示例演示如何使用线程解决生产者消费者问题. package com.yiibai; public class ProducerConsumer ...
- java命令分析线程死锁以及内存泄漏
一.介绍 jstack是java虚拟机自带的一种堆栈跟踪工具.jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项&qu ...
- Java虚拟机性能管理神器 - VisualVM(9) 排查JAVA应用程序线程死锁【转】
Java虚拟机性能管理神器 - VisualVM(9) 排查JAVA应用程序线程死锁[转] 标签: javajvm监控工具性能优化 2015-03-11 19:59 1948人阅读 评论(0) 收藏 ...
- java笔记--关于线程死锁
关于线程死锁 什么是死锁: 在编写多线程的时候,必须要注意资源的使用问题,如果两个或多个线程分别拥有不同的资源, 而同时又需要对方释放资源才能继续运行时,就会发生死锁. 简单来说:死锁就是当一个或多个 ...
- 浅谈利用同步机制解决Java中的线程安全问题
我们知道大多数程序都不会是单线程程序,单线程程序的功能非常有限,我们假设一下所有的程序都是单线程程序,那么会带来怎样的结果呢?假如淘宝是单线程程序,一直都只能一个一个用户去访问,你要在网上买东西还得等 ...
- java多线程之 ---- 线程死锁
java多线程之线程死锁 产生死锁的主要原因: 由于系统资源不足. 进程执行推进的顺序不合适. 资源分配不当等. 假设系统资源充足.进程的资源请求都可以得到满足,死锁出现的可能性就非常低.否则就会因争 ...
- Java多线程——线程的死锁
Java多线程——线程的死锁 摘要:本文主要介绍了Java多线程中遇到的死锁问题. 部分内容来自以下博客: https://www.cnblogs.com/wy697495/p/9757982.htm ...
- Java并发3-多线程面试题
1) 什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速. 2) 线程和进程有什 ...
- Java多线程之线程的通信
Java多线程之线程的通信 在总结多线程通信前先介绍一个概念:锁池.线程因为未拿到锁标记而发生的阻塞不同于前面五个基本状态中的阻塞,称为锁池.每个对象都有自己的锁池的空间,用于放置等待运行的线程.这些 ...
随机推荐
- The Linux Command Line,Script
https://stackoverflow.com/questions/5891342/modify-conf-file-with-shell-script http://www.grymoire.c ...
- std::bind技术内幕
引子 最近群里比较热闹,大家都在山寨c++11的std::bind,三位童孩分别实现了自己的bind,代码分别在这里: 木头云的实现 mr.li的实现 null的实现,null的另一个版本的实现 这些 ...
- GDB 调试解析
GDB(GNU Debugger)是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行序 列,形成脚本.UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优 ...
- 获取windows可执行文件的version信息(版本号)
之前在msdn上Version Information看到文件版本信息的介绍,看着整体比较复杂,就一直没做.现在需要获取ocx文件的版本号,所以查找了下相关资料,比较有用的就是VS_FIXEDFILE ...
- xml属性定义
1. reference:参考某一资源ID. 1)属性定义: <declare-styleable name="名称"> <attr format="r ...
- import-module的注意事项与NDK_MODULE_PATH的配置
转:http://blog.sina.com.cn/s/blog_4057ab62010197z8.html 具体的语句多参考其他正确的Android.mk import-module的功能 导入 ...
- iOS贝塞尔曲线(UIBezierPath)的基本使用方法
简介 UIBezierPath是对Core Graphics框架的一个封装,使用UIBezierPath类我们可以画出圆形(弧线)或者多边形(比如:矩形)等形状,所以在画复杂图形的时候会经常用到. 分 ...
- Sublime Text 3安装与使用,安装插件,快捷键,默认配置
本文是Sublime Text 全程指引 by Lucida (http://www.cnblogs.com/figure9/p/sublime-text-complete-guide.html)的笔 ...
- Android Retrofit2 网路编程
Android里面本身有OKHttp,不过不是很好用,这里就用Retrofit2,简单好用. 首先,需要加入网络权限: <uses-permission android:name="a ...
- 【Linux/CentOS】Boolean ftp_home_dir is not defined
安装完vsftpd软件后,因为CentOS系统的SELinux安全策略默认是没有开启FTP服务,直接访问会报错500 OOPS,所以需要修改为允许使用FTP服务. 目标:希望ftp用户可以访问自己的家 ...