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多线程之线程的通信 在总结多线程通信前先介绍一个概念:锁池.线程因为未拿到锁标记而发生的阻塞不同于前面五个基本状态中的阻塞,称为锁池.每个对象都有自己的锁池的空间,用于放置等待运行的线程.这些 ...
随机推荐
- JVM源码分析之安全点safepoint
https://blog.csdn.net/iter_zc/article/details/41892567 https://www.jianshu.com/p/c79c5e02ebe6
- Silverlight-MEF-DEMO
“托管扩展性框架(Managed Extensibility Framework,简称MEF),是微软.NET框架下为提高应用和组件复用程度而推出的,用于使组件能够最大化的重用.使用MEF能够使静态编 ...
- mysql关联更新update
https://blog.csdn.net/babyfish13/article/details/78082844 ****************************************** ...
- Windows删除/修改注册表权限不足的解决方法
在注册表的某些关键项(譬如:System.Root),连Administrator都没有权限进行修改,因为只有“system”有权限. [警告]切勿企图进行注册表上层权限覆盖低层权限的方式来使Admi ...
- C#数组 添加元素
例1: string[] a = new string[] { "1", "2", "3" }; 给a追加一个 "4" ...
- python版本坑:md5例子(python2与python3中md5区别)
对于一些字符,python2和python3的md5加密出来是不一样的. Python2 和Python3MD5加密 # python2.7 pwd = "xxx" + chr(1 ...
- Mybatis缓存理解
缓存 接触过hibernate的同学都知道hibernate中有个二级缓存,mybatis也存在二级缓存.mybatis中二级缓存有什么作用呢?mybatis提供查询缓存,可以提高查询效率,减轻数据库 ...
- 网络构建入门技术(1)——IP概述
说明(2017-5-10 11:02:31): 0. IP地址的作用,TCP/IP,网络层,包,源IP(哪个设备发出).目的IP(数据要发到哪个设备),每个设备需要唯一的一个IP地址.32个0到32个 ...
- 基于css3 transform实现散乱的照片排列
分享一款基于css3 transform实现散乱的照片排列.这是一款简单零散的css3相册排列特效下载.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div class= ...
- git pull出现There is no tracking information for the current branch
使用git pull 或者 git push 的时候报错 gitThere is no tracking information for the current branch. Please spec ...