版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/love_world_/article/details/27635333

一、死锁

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

百科百科

当两个以上的运算单元,两方都在等待对方停止运行,以取得系统资源。可是没有一方提前退出时,这样的状况,就称为死锁。维基百科

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<Taxi> taxis;
private final Set<Taxi> avaliableTaxis; public Dispatcher(){
taxis = new HashSet<Taxi>();
avaliableTaxis = new HashSet<Taxi>();
} 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并发程序设计教程》

《Java并发编程实战》第十章 避免活跃性危急 读书笔记的更多相关文章

  1. 《Java并发编程实战》第六章 任务运行 读书笔记

    一. 在线程中运行任务 无限制创建线程的不足 .线程生命周期的开销很高 .资源消耗 .稳定性 二.Executor框架 Executor基于生产者-消费者模式.提交任务的操作相当于生产者.运行任务的线 ...

  2. 《Java并发编程实战》第五章 同步容器类 读书笔记

    一.同步容器类 1. 同步容器类的问题 线程容器类都是线程安全的.可是当在其上进行符合操作则须要而外加锁保护其安全性. 常见符合操作包括: . 迭代 . 跳转(依据指定顺序找到当前元素的下一个元素) ...

  3. 《Java并发编程实战》第十三章 显示锁 读书笔记

    一.Lock与 ReentrantLock Lock 提供一种无条件的.可轮询的.定时的.可中断的锁获取操作,全部加锁和解锁的方法都是显式的. public interface Lock { void ...

  4. java并发编程(3)避免活跃性危险

    活跃性危险 一.死锁 发生:每个人都不愿意放弃自己的锁,确想要别人的锁,这就会导致死锁  1.锁顺序死锁:如果每个线程以固定的顺序获取锁,那么至少在程序中不会出现锁顺序导致的死锁: 因为顺序固定如:所 ...

  5. Java并发编程实战 05等待-通知机制和活跃性问题

    Java并发编程系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 Java并发编程实战 03互斥锁 解决原子性问题 Java并发编程实 ...

  6. 《Java并发编程实战》/童云兰译【PDF】下载

    <Java并发编程实战>/童云兰译[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062521 内容简介 本书深入浅出地介绍了Jav ...

  7. 《java并发编程实战》笔记

    <java并发编程实战>这本书配合并发编程网中的并发系列文章一起看,效果会好很多. 并发系列的文章链接为:  Java并发性和多线程介绍目录 建议: <java并发编程实战>第 ...

  8. Java并发编程实战.笔记十一(非阻塞同步机制)

    关于非阻塞算法CAS. 比较并交换CAS:CAS包含了3个操作数---需要读写的内存位置V,进行比较的值A和拟写入的新值B.当且仅当V的值等于A时,CAS才会通过原子的方式用新值B来更新V的值,否则不 ...

  9. Java并发编程实战——读后感

    未完待续. 阅读帮助 本文运用<如何阅读一本书>的学习方法进行学习. P15 表示对于书的第15页. Java并发编程实战简称为并发书或者该书之类的. 熟能生巧,不断地去理解,就像欣赏一部 ...

随机推荐

  1. 通过helloworld来认识下backbone

    Backbone主要涉及3部分:model,collection和view.而这个框架的优势在于:数据与视图分离,通过操作model来自动更新view. 根据我的个人经验,直接写个简单的例子是最最直观 ...

  2. day18-事务与连接池 1.复习

    实际开发中事务必须得用.

  3. 【FZU 2277】Change

    题意 有一颗有n个节点的有根树,根节点编号时1,每个结点都有一个值ai,开始的时候,所有节点的值都是0. 我们有q个操作,操作只有两种类型 1 v x k,a[v]+=x,a[v']+=x-k,a[v ...

  4. 刷题向》关于一道像差分约束的数学题BZOJ1045(NORMAL)

    关于这道题,乍一看很像查分约束,但是实际上这道题是可以用数学方法直接解决的. 这道题在蓝书上有原题,可以看到题解,在此再赘述一遍 首先,最终每个小朋友的糖果数量可以计算出来,等于糖果总数除以n,用av ...

  5. PHP格式化(文件)存储数据大小(SIZE)显示

    有时候我们需要在网页上显示某个文件的大小,或者是其它数据的大小数字. 这个数字往往从跨度很大,如果以B为单位的话可能是个位,如果1G则长达1073741824的数字,这个时候我们就需要根据大小来格式化 ...

  6. http请求和返回的head字段

    一,http请求分请求首部字段,通用首部字段,实体首部字段.http响应包含响应首部字段,通用首部字段,实体首部字段. 二,http1.1定义了47种首部字段.1,通用首部字段:cache-contr ...

  7. 2.3.1 java 内存模型

    在前面谈到了一些关于内存模型以及并发编程中可能会出现的一些问题.下面我们来看一下Java内存模型,研究一下Java内存模型为我们提供了哪些保证以及在java中提供了哪些方法和机制来让我们在进行多线程编 ...

  8. ASP.NET MVC 3 and the @helper syntax within Razor

    Friday, May 13, 2011 ASP.NET MVC 3 supports a new view-engine option called “Razor” (in addition to ...

  9. jquery数组拼接

    var a=[]; var c=[80,90,70,100] var b={'张三':19,'成绩':c}; a.push(b); console.log("测试案例",a); 同 ...

  10. wp面试题

    初级工程师 解释什么是依赖属性,它和以前的属性有什么不同?为什么在WPF会使用它? 什么是样式什么是模板 绑定(Binding )的基础用法 解释这几个类的作用及关系: Visual, UIEleme ...