JAVA并发编程学习笔记------锁顺序死锁
一、需求描述:
将资金从一个账户转移到另一个账户。
二、程序实现:
(1)账户类:
public class Account {
private long account;
public Account(String user, long account) {
this.account = account;
}
public Account() {
super();
}
public long getAccount() {
return account;
}
public void setAccount(long account) {
this.account = account;
}
public void debit(long money){
this.account -= money;
}
public void credit(long money){
this.account += money;
}
}
(2)资产转移类:
public class TransMoney {
private static final Object tieLock = new Object();
public static void transferMoney(Account fromAccount,Account toAccount,long amount){
synchronized (fromAccount){
synchronized (toAccount){
fromAccount.debit(amount);
toAccount.credit(amount);
}
}
}
}
(3)测试类:
public class DemonstrateDeadLock {
private static final int NUM_THREADS = 20;
private static final int NUM_ACCOUNTS = 5;
private static final int NUM_ITERATIONS = 1000000;
public static void main(String[] args) {
final Random rdn = new Random();
final Account[] accounts = new Account[NUM_ACCOUNTS];
for(int i=0;i<accounts.length;i++){
accounts[i] = new Account();
}
class TransferThread extends Thread{
public void run(){
for(int i=0;i<NUM_ITERATIONS;i++){
int fromAccount = rdn.nextInt(NUM_ACCOUNTS);
int toAccount = rdn.nextInt(NUM_ACCOUNTS);
TransMoney.transferMoney(accounts[fromAccount],accounts[toAccount],rdn.nextInt(1000));
}
}
}
for(int i=0;i<NUM_THREADS;i++){
new TransferThread().start();
}
}
}
(4)解析:
上述程序容易形成死锁,原因在于多账户调用TransMoney.transferMoney时,存在锁顺序冲突,
解决方案是使用System.identityHashCode来定义锁的顺序,消除死锁的可能性,代码实现如下:
public static void transferMoney(final Account fromAccount,final Account toAccount,final long amount){
class Helper{
public void transfer(){
fromAccount.debit(amount);
toAccount.credit(amount);
}
}
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();
}
}
}
}
}
JAVA并发编程学习笔记------锁顺序死锁的更多相关文章
- Java并发编程学习笔记
Java编程思想,并发编程学习笔记. 一.基本的线程机制 1.定义任务:Runnable接口 线程可以驱动任务,因此需要一种描述任务的方式,这可以由Runnable接口来提供.要想定义任务,只需实现R ...
- Java 并发编程学习笔记 理解CLH队列锁算法
CLH算法实现 CLH队列中的结点QNode中含有一个locked字段,该字段若为true表示该线程需要获取锁,且不释放锁,为false表示线程释放了锁.结点之间是通过隐形的链表相连,之所以叫隐形的链 ...
- Java并发编程学习笔记 深入理解volatile关键字的作用
引言:以前只是看过介绍volatile的文章,对其的理解也只是停留在理论的层面上,由于最近在项目当中用到了关于并发方面的技术,所以下定决心深入研究一下java并发方面的知识.网上关于volatile的 ...
- JAVA并发编程学习笔记------协作对象之间发生的死锁
一. 如果在持有锁时调用某个外部方法,那么将出现活跃性问题.在这个外部方法中可能会获取其他锁(这可能会产生死锁),或者阻塞时间过长,导致其他线程无法及时获得当前被持有的锁.如下代码: public c ...
- JAVA并发编程学习笔记------多线程调优
1. 多线程场景下尽量使用并发容器代替同步容器 (如ConcurrentHashMap代替同步且基于散列的Map, 遍历操作为主要操作的情况下用CopyOnWriteArrayList代替同步的Lis ...
- Java并发编程学习笔记(一)——线程安全性
主要概念:线程安全性.原子性.原子变量.原子操作.竟态条件.复合操作.加锁机制.重入.活跃性与性能. 1.当多个线程访问某个状态变量并且其中有一个线程执行写入操作时,必须采用同步机制来协同这些线程对变 ...
- JAVA并发编程学习笔记之ReentrantLock
ReentrantLock是一个可重入的互斥锁,ReentrantLock由最近成功获取锁,还没有释放的线程所拥有,当锁被另一个线程拥有时,调用lock的线程可以成功获取锁.如果锁已经被当前线程拥有, ...
- Java并发编程学习笔记(二)——对象的共享
主要概念:可见性.重排序.失效数据.最低安全性.发布.逸出.线程封闭(Ad-hoc.栈封闭.ThreadLocal类).不变性.Final域.事实不可变对象. 1.在没有同步的情况下,编译器.处理器以 ...
- java并发编程学习笔记(一)初识并发原子性
1.并发的意义 现在是一个多核的时代,并发的存在意义就是为了能够充分利用多核计算机的优势,提高程序的运行效率: 2.并发的风险 竞争-----多个线程对内存数据数据进行读写操作时,对数据处理结果的一个 ...
随机推荐
- Eclipse卡顿,内存猛增解决方案
本文转载自http://rsy.iteye.com/blog/2095668/ PS:所有校验都去除后,对如下版本来说,内存一直猛增,解决办法参照上放博客:修改项目的.project文件,特此备注记录 ...
- Spring(一)Spring的第一滴血
前言 开始工作了,但是一进来公司本来是做爬虫和数据分析的,但是走了一个后端的,导致我必须要去顶替他的工作.因为这个项目使用的是Spring. SpringMVC.Hibernate所以我又要去回忆一下 ...
- D. Longest Subsequence
D. Longest Subsequence time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- maven学习3,如何创建一个web项目
Maven学习 (三) 使用m2eclipse创建web项目 1.首先确认你的eclipse已经安装好m2eclipse的环境,可以参照上两篇Maven学习内容 2.新建一个maven的项目 ...
- 设置Sql server用户对表、视图、存储过程、架构的增删改查权限
根据数据库Schema限制用户对数据库的操作行为 授予Shema dbo下对象的定义权限给某个用户(也就是说该用户可以修改架构dbo下所有表/视图/存储过程/函数的结构) use [Your DB N ...
- lnmp14最新版
系统需求: CentOS/RHEL/Fedora/Debian/Ubuntu/Raspbian/Deepin Server/Aliyun/Amazon/Mint Linux发行版 需要5GB以上硬盘剩 ...
- 01 整合IDEA+Maven+SSM框架的高并发的商品秒杀项目之业务分析与DAO层
作者:nnngu 项目源代码:https://github.com/nnngu/nguSeckill 这是一个整合IDEA+Maven+SSM框架的高并发的商品秒杀项目.我们将分为以下几篇文章来进行详 ...
- ArrayList 源码详细分析
1.概述 ArrayList 是一种变长的集合类,基于定长数组实现.ArrayList 允许空值和重复元素,当往 ArrayList 中添加的元素数量大于其底层数组容量时,其会通过扩容机制重新生成一个 ...
- input===》name属性异常错误
<input type="text" name="status" /> 使用springMVC时,如果有这个输入框,此框必须要填,且必须是数字,否者 ...
- 编程:在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串 'welcome to masm!'
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...