首页 技术 正文
技术 2022年11月15日
0 收藏 414 点赞 3,970 浏览 1943 个字

一、需求描述:

  将资金从一个账户转移到另一个账户。

二、程序实现:

(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();
}
}
}
}
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,954
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,479
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,291
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,108
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,740
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,774