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多线程之线程的通信 在总结多线程通信前先介绍一个概念:锁池.线程因为未拿到锁标记而发生的阻塞不同于前面五个基本状态中的阻塞,称为锁池.每个对象都有自己的锁池的空间,用于放置等待运行的线程.这些 ...
随机推荐
- DataTable的初始化与事件注册
TypeScript代码: let tabledata = data as any[]; if (this.dataTable) { this.dataTable.clear(); this.data ...
- 网页安装ipa
在网页上直接下载并安装ipa,兼容所欲iso,包含没有越狱的 1.html代码 <a href="itms-services://?action=download-manifest&a ...
- 使用 IDEA 开发工具(版本为 IntelliJ IDEA 14.1.4)打可执行jar包的操作步骤
声明:教程演示使用的开发工具的版本是 IntelliJ IDEA 14.1.4. 1.选择IDEA开发工具菜单栏 File --> Project Structure,弹出如下窗口,在左侧的列表 ...
- Python之Flask和Django框架解决跨域问题,配合附加ajax和fetch等js代码
Flask框架py解决跨域问题示例: # -*- coding: utf- -*- # by zhenghai.zhang from flask import Flask, render_templa ...
- 练习1 Just Java
任务:做这样一个界面,选择数量,自动计算价格.超级简单.. <?xml version="1.0" encoding="utf-8"?> <a ...
- JS实现多行文本最后是省略号紧随其后还有个超链接在同一行的需求
1.布局及样式如下图: 2.js获得上图的div对象,然后判断div对象的高度,如果大于一行的高度了表示内容有两行了,再获得span标签里面的内容并用正则将后六个字符替换成“......”这里的实现代 ...
- Android 下拉刷新上啦加载SmartRefreshLayout + RecyclerView
在弄android刷新的时候,可算是耗费了一番功夫,最后发觉有现成的控件,并且非常好用,这里记录一下. 原文是 https://blog.csdn.net/huangxin112/article/de ...
- 火狐FireFox57不支持Tab Mix Plus插件的问题
火狐的Tab Mix Plus插件管理标签页很好用,但是在这次升级到57版本后不能用了,也没找到合适的替代品. 该插件一个很常用的功能是在新建的标签页打开网页(而不是在当前页上跳转),该功能直接修改C ...
- C#使用ActiveMQ实例
1. ActiveMQ消息总线简介 消息队列(Message Queue,简称MQ),从字面意思上看,本质是个队列,FIFO先入先出,只不过队列中存放的内容是message而已.主要用作不同进程.应用 ...
- C++学习笔记(HelloWorld,类型和值)
现在有一个从控制台读取输入的小程序: #include "../std_lib_facilities.h" int main() { cout << "Ple ...