首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ReentrantLock -同时转账业务

ReentrantLock -同时转账业务
EN

Stack Overflow用户
提问于 2018-12-25 12:20:14
回答 2查看 1.1K关注 0票数 1

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

代码语言:javascript
复制
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有关的并发问题:

代码语言:javascript
复制
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的or ()方法(与ReentrantLock字段同步或锁定)吗?难道其他线程不可能潜入并调用取款或存款方法吗?此外,如果有getBalance()方法,怎么办?它是否也应该受到保护(与ReentrantLock同步或锁定)?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-12-25 12:36:37

有两种选择:

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

这才是我想要的。作为API的使用者,除了Account#withdrawAccount#deposit之外,我想要自给自足,所以不需要额外的操作。

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

(2)将提供正确性和线程安全的责任放在调用方。你不在乎它是如何实现的。

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

票数 0
EN

Stack Overflow用户

发布于 2018-12-25 12:41:25

帐户的取款()和存款()方法不应该受到某种保护吗?

实际上,当下面的代码行执行时,代码块被Lock对象保护(每个帐户对象都有自己的Lock对象)。因此,没有其他线程可以使用相同的Account实例执行相同的代码。

代码语言:javascript
复制
while(true)
    {
      if(from.lock.tryLock()){
        try { 
            if (to.lock.tryLock()){
               try{
          ....
          ....

另一方面,当您执行代码时,您正在创建多个Account对象,这使得每个传输相互独立。每个Account对象都有自己的状态(balancelock )

此外,如果有getBalance()方法,怎么办?它也应该受到保护吗?

如上段所述。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53922340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档