gpt4 book ai didi

java - ReentrantLock - 并发转账操作

转载 作者:太空宇宙 更新时间:2023-11-04 09:57:36 24 4
gpt4 key购买 nike

当我在互联网上阅读一些并发代码示例时,我发现了这个(2个银行帐户之间的转账操作):

class Account {
double balance;
int id;
public Account(int id, double balance){
this.balance = balance;
this.id = id;
}
void withdraw(double amount){
balance -= amount;
}
void deposit(double amount){
balance += amount;
}
}
class Main{
public static void main(String [] args){
final Account a = new Account(1,1000);
final Account b = new Account(2,300);
Thread a = new Thread(){
public void run(){
transfer(a,b,200);
}
};
Thread b = new Thread(){
public void run(){
transfer(b,a,300);
}
};
a.start();
b.start();
}

这段代码使用 ReentrantLock 处理并发问题:

private final Lock lock = new ReentrantLock(); //Addition to the Account class

public static void transfer(Account from, Account to, double amount)
{
while(true)
{
if(from.lock.tryLock()){
try {
if (to.lock.tryLock()){
try{
from.withdraw(amount);
to.deposit(amount);
break;
}
finally {
to.lock.unlock();
}
}
}
finally {
from.lock.unlock();
}

Thread.sleep(someRandomTimeToPreventLiveLock);
}
}

我的问题是:为了让这个示例正常工作,Acount的withdraw()和deposit()方法不应该受到某种保护(与ReentrantLock字段同步或锁定)吗?其他线程是否有可能潜入并调用取款或存款方法?另外,如果有 getBalance() 方法怎么办?它也应该受到保护(与 ReentrantLock 同步或锁定)吗?

最佳答案

有两个选项:

(1) 您使您的类成为线程安全的,这意味着对该类的任何实例的任何操作都受到某种内部机制的保护,并且在多线程环境中绝对安全。调用方不应该关心线程安全。

这就是我在这里更喜欢的。作为 API 的使用者,我认为 Account#withdrawAccount#deposit 都是自给自足的,因此不需要额外的操作。

在我看来,这就是一个好的 API。

(2) 您将提供正确性和线程安全性的责任置于调用方。你并不关心如何实现它。

这就是您的代码片段当前的工作方式。 transfer 方法是线程安全的,但它不会使帐户操作如此。

关于java - ReentrantLock - 并发转账操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53922340/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com