博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《Java并发编程实战》第十章 避免活跃性危急 读书笔记
阅读量:4700 次
发布时间:2019-06-09

本文共 3658 字,大约阅读时间需要 12 分钟。

一、死锁

所谓死锁: 是指两个或两个以上的进程在运行过程中。因争夺资源而造成的一种互相等待的现象。若无外力作用。它们都将无法推进下去。


当两个以上的运算单元,两方都在等待对方停止执行,以取得系统资源,可是没有一方提前退出时,这样的状况,就称为死锁。
1. 顺序死锁
最少有两个锁。一个线程获取到A锁须要获取B锁才干进行操作,而另外一个线程获取到了B锁。须要获取A锁才干运行操作。这样的情况下easy出现顺序死锁。
public class LeftRightDeadlock {	private final Object left = new Object();	private final Object right = new Object();	public void leftRight() {		synchronized (left) {			synchronized (right) {				// doSomething();			}		}	}	public void rightLeft() {		synchronized (right) {			synchronized (left) {				// doSomething();			}		}	}}
2. 动态的锁顺序死锁
public void transferMoney(Account fromAccount, Account toAccount, DollarAmount anount)			throws InsufficientResourcesException {		synchronized (fromAccount) {			synchronized (toAccount) {				if (fromAccount.getBalance().compareTo(amount) < 0) {					throw new InsufficientResourcesException();				} else {					fromAccount.debit(anount);					toAccount.credit(anount);				}			}		}	}
A: transferMoney(myAccount, yourAccount, 10);
B: transferMoney(yourAccount, myAccount, 20);
由外部传入的变量全部锁的条件,可是由以上传入的变量能够看到,这样的情况下会出现一个线程先获取myAccount锁在申请yourAccount锁,而另外一个线程相反先获取yourAccount锁在申请myAccount锁。
private static final Object tieLock = new Object();	public void transferMoney(final Account fromAccount, final Account toAccount, final DollarAmount anount)			throws InsufficientResourcesException {		class Helper{		    public void transfer() throws InsufficientResourcesException {		        if (fromAccount.getBalance().compareTo(amount) < 0){		        	throw new InsufficientResourcesException();		        } else{					fromAccount.debit(anount);					toAccount.credit(anount);		        }		    }		}		int fromHash = System.identityHashCode(fromAccount);		int toHash = System.identityHashCode(toAccount);			if (fromHash < toHash){		    synchronized (fromAccount){		        synchronized (toAccount) {		            new Helper().transfer();		        }		    }		} else if (fromHash >  toHash){		    synchronized (toAccount){		        synchronized (fromAccount) {		            new Helper().transfer();		        }		    }		} else {		    synchronized (tieLock) {		        synchronized (fromAccount) {		            synchronized (toAccount) {		                new Helper().transfer();		            }		        }		    }		}	}
3. 在协作对象之间发生的死锁
class Taxi {	private Point location, destination;	private final Dispatcher dispatcher;	public Taxi(Dispatcher dispatcher) {	    this.dispatcher = dispatcher;	}		public synchronized Point getLocation(){	    return location;	}	public synchronized void setLocation(Point location){	    this.location = location;	    if (location.equals(destination)){	        dispatcher.notifyAvaliable(this);	    }	}} class Dispatcher {	private final Set
taxis; private final Set
avaliableTaxis; public Dispatcher(){ taxis = new HashSet
(); avaliableTaxis = new HashSet
(); } public synchronized void notifyAvaliable(Taxi taxi) { avaliableTaxis.add(taxi); } public synchronized Image getImage(){ Image image = new Image(); for (Taxi t :taxis){ image.drawMarker(t.getLocation()); } return image; }}
4. 开放调用
 -- 待填充
5. 资源死锁
外部锁常被忽视而导致死锁,比如数据库的锁

二、死锁的避免与诊断

1. 支持定时的死锁
存在一些预防死锁的手段。比方Lock的tryLock,JDK 7中引入的Phaser等。

2. 通过线程转储信息来分析死锁
通过Dump线程的StackTrace,比如linux下运行命令 kill -3 <pid>,或者jstack –l <pid>,或者使用Jconsole连接上去查看线程的StackTrace,由此来诊断死锁问题。

三、其它活跃性危急

1. 饥饿
2. 糟糕的响应性
3. 活锁

四、锁的使用

使用支持CAS的数据结构。避免使用锁。如:AtomicXXX、ConcurrentMap、CopyOnWriteList、ConcurrentLinkedQueue
死锁常常是无法全然避免的,鸵鸟策略被非常多基础框架所採用。

存在检測死锁的办法

五、參考资料:

《温绍锦 - Java并发程序设计教程》

转载于:https://www.cnblogs.com/brucemengbm/p/6817889.html

你可能感兴趣的文章
【JBPM4】判断节点decision 方法3 handler
查看>>
filter 过滤器(监听)
查看>>
node启动时, listen EADDRINUSE 报错;
查看>>
杭电3466————DP之01背包(对状态转移方程的更新理解)
查看>>
kafka中的消费组
查看>>
python--注释
查看>>
SQL case when else
查看>>
SYS_CONTEXT 详细用法
查看>>
Pycharm配置autopep8让Python代码更符合pep8规范
查看>>
我的第一篇博客
查看>>
【C++算法与数据结构学习笔记------单链表实现多项式】
查看>>
C#垃圾回收机制
查看>>
31、任务三十一——表单联动
查看>>
python之hasattr、getattr和setattr函数
查看>>
maven使用阿里镜像配置文件
查看>>
Copy code from eclipse to word, save syntax.
查看>>
arguments.callee的作用及替换方案
查看>>
P2709 小B的询问
查看>>
PHP echo 和 print 语句
查看>>
第一讲 一个简单的Qt程序分析
查看>>