package cn.study.concurrency.ch10;

public class Account {
private String staffAccount; //账号
private String passWord; //密码
private int balance; //账户余额 public Account(int money) {
this.balance = money;
} public String getStaffAccount() {
return staffAccount;
}
public void setStaffAccount(String staffAccount) {
this.staffAccount = staffAccount;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
} public void debit(int amount)
{
System.out.println("转出账户:" + amount);
} public void credit(int amount)
{
System.out.println("转入账户:" + amount);
}
public int getBalance() {
return balance;
}
public void setBalance(int balance) {
this.balance = balance;
} }
package cn.study.concurrency.ch10;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import javax.naming.InsufficientResourcesException; /**
* 通过制定确定的锁顺序来避免死锁
* @author xiaof
*
*/
public class DeathLock {
public void transferMoney(Account fromAccount, Account toAccount, int amount) throws InsufficientResourcesException
{
synchronized(fromAccount)
{
synchronized(toAccount)
{
//按参数的顺序上锁,这个依据参数的调用方法的顺序
if(fromAccount.getBalance() < amount)
{
//账户余额不足,无法转账
throw new InsufficientResourcesException();
}
else
{
fromAccount.debit(amount);
toAccount.credit(amount);
}
}
}
}
/**
* 这个用来在无法判定枷锁顺序的时候的加时赛锁
*/
private static final Object tieLock = new Object(); public static void transferMoney2(final Account fromAccount, final Account toAccount, final int amount) throws InsufficientResourcesException
{
/**
* 辅助内部类
* @author xiaof
*
*/
class Helper
{
public void transfer() throws InsufficientResourcesException
{
//内部类可以随意访问外部类成员
//按参数的顺序上锁,这个依据参数的调用方法的顺序
if(fromAccount.getBalance() < amount)
{
//账户余额不足,无法转账
throw new InsufficientResourcesException();
}
else
{
fromAccount.debit(amount);
toAccount.credit(amount);
}
}
}
//返回给定对象的哈希码,该代码与默认的方法 hashCode() 返回的代码一样,无论给定对象的类是否重写 hashCode()
int fromHash = System.identityHashCode(fromAccount);
int toHash = System.identityHashCode(toAccount);
//根据hash值判定加锁顺序,那么一样的对象的锁顺序就一定一样
if(fromHash < toHash)
{
synchronized(fromAccount)
{
synchronized(toAccount)
{
new Helper().transfer();
}
}
}
else if(toHash < fromHash)
{
synchronized(toAccount)
{
synchronized(fromAccount)
{
new Helper().transfer();
}
}
}
else
{
//如果很不巧,hash值是一样的,那么就需要一个加时赛的机制,先获取外部锁,然后再此基础上对两个对象随机上锁
synchronized(tieLock)
{
synchronized(fromAccount)
{
synchronized(toAccount)
{
new Helper().transfer();
}
}
}
} } static Account account1 = new Account(999);
static Account account2 = new Account(999); public static void main(String[] args) throws InsufficientResourcesException {
//对于第一个方法很容易死锁
//比如:当有两个同时执行这个方法的调用时候
// DeathLock dl = new DeathLock();
//这个时候第一个调用在锁了account1,然后第二个调用锁了account2
//同时第一个需要account2,第二个需要account1,这就发生竞争死锁了
// dl.transferMoney(account1, account2, 998);
// dl.transferMoney(account2, account1, 998);
//
// dl.transferMoney2(account1, account2, 998);
ExecutorService pool = Executors.newFixedThreadPool(10);
for(int i = 0; i < 5; ++ i)
{
pool.execute(new Runnable() {
@Override
public void run() {
try {
DeathLock.transferMoney2(account1, account2, 998);
} catch (InsufficientResourcesException e) {
e.printStackTrace();
}
}
});
} for(int i = 0; i < 5; ++ i)
{
pool.execute(new Runnable() {
@Override
public void run() {
try {
DeathLock.transferMoney2(account2, account1, 998);
} catch (InsufficientResourcesException e) {
e.printStackTrace();
}
}
});
} pool.shutdown();
}
}

测试结果:

【JAVA并发编程实战】8、锁顺序死锁的更多相关文章

  1. JAVA并发编程学习笔记------锁顺序死锁

    一.需求描述: 将资金从一个账户转移到另一个账户. 二.程序实现: (1)账户类: public class Account { private long account; public Accoun ...

  2. java并发编程实战《五》死锁

    一不小心就死锁了,怎么办? 在上一篇文章中,我们用 Account.class 作为互斥锁,来解决银行业务里面的转账问题,虽然这个方案不存在并发问题,但是所有账户的转账操作都是串行的,性能太差. 向现 ...

  3. Java并发编程实战(4)- 死锁

    在这篇文章中,我们主要讨论一下死锁及其解决办法. 目录 概述 死锁案例 死锁的原因和预防 破坏占用且等待条件 破坏不可抢占条件 破坏循环条件 使用等待-通知机制 Java中的等待-通知机制 条件曾经满 ...

  4. Java并发编程实战 04死锁了怎么办?

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

  5. Java并发编程实战 03互斥锁 解决原子性问题

    文章系列 Java并发编程实战 01并发编程的Bug源头 Java并发编程实战 02Java如何解决可见性和有序性问题 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和 ...

  6. 【Java并发编程实战】----- AQS(二):获取锁、释放锁

    上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...

  7. 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock

    ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...

  8. 【Java并发编程实战】-----“J.U.C”:ReentrantLock之一简介

    注:由于要介绍ReentrantLock的东西太多了,免得各位客官看累,所以分三篇博客来阐述.本篇博客介绍ReentrantLock基本内容,后两篇博客从源码级别分别阐述ReentrantLock的l ...

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

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

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

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

随机推荐

  1. TODO:关于自媒体博客改名

    TODO:关于自媒体博客改名 1.微信公众号:ludong86 个人类帐号一个自然年内可主动修改两次名称 2.企鹅号 不能改帐号名称 3.简书 名称可以随意修改,但是个人主页是系统自动生成的. 4.今 ...

  2. Intellij IDEA 13.1.3 字体,颜色,风格设置

    作者QQ:1095737364 打开file-->settings,然后根据提示完成设置,当然,可以根据自己的爱好设置自己的风格,那个工程区的背景我还没有找到在什么地方,如果你找到了麻烦告诉我一 ...

  3. Nginx负载均衡的详细配置及使用案例详解.

    感谢看过这一些列博文和评论的小伙伴, 我把自己所看到的学到的拿到这里来分享是想和大家一起学习进步, 想听听园友给出的意见, 也是对自己学习过程的一个总结. 技术无止境, 我们仍需努力! 1,话不多说, ...

  4. Windows中搭建Redis集群

    从 http://rubyinstaller.org/downloads/ 下载Ruby2.2.5(x64)并安装,安装时勾选添加至路径变量中 命令行中执行gem source -a http://g ...

  5. WPF自定义控件与样式(2)-自定义按钮FButton

    一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 还是先看看效果 ...

  6. SQL 联合查询 + XML解析

    (select a.EBILLNO, a.EMPNAME, a.APPLYDATE, b.HS_NAME, ), ),'') as SUMMARY, cast(c.XmlData as XML).va ...

  7. zyUpload+struct2完成文件上传

    前言: 最近在写自己的博客网站,算是强化一下自己对s2sh框架的理解.期间遇到了很多问题,这些问题在写之前都考虑过,感觉也就是那样吧.但正真遇到了,也挺让人难受的.就利用zyUpload这个js插件实 ...

  8. Easyui 让Window弹出居中与最大化后居中

    easyui1.3.2版本,window的弹出不会居中了.而dialog是会居中的,我们必须为为window的open事件做扩展 代码如下:只要加入以下代码即可.如果你是看了MVC项目系列的,把他放到 ...

  9. 【开源】OSharp3.3框架解说系列:重新开源及3.3版本新特性

    OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...

  10. 门外汉的IT

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 计算机很早就走入了我的生活.小学时,家里放一台联想“天琴”的电脑.它霸气的音箱造型 ...