java - 如何使方法线程安全,即使我忘记在不更改文件的情况下在方法或 block 级别添加同步?

标签 java multithreading synchronized

在一家知名公司的面试中,我遇到了这样的问题:

你有一个类,你的同事忘了同步一些重要的方法 如何在不更改同一类的情况下使其线程安全?

public class Account{

    //some variables

    public boolean withdraw()
    {
        //some business logic
        return true;
    }

    public boolean deposite()
    {
        //some business logic
        return false;
    }
}

我不确定答案是什么,也可能是愚蠢的答案。请帮助我得到答案。

我的回答: 我给出了答案,就像我们可以对其进行包装并且我们可以同步。这不是令人信服的答案,我认为这是获得答案的最佳平台

最佳答案

我在这里看到两个可能的答案:

  1. 扩展 Acount 类并同步方法访问:
public class SyncrhonizedAccess extends Account {
   public synchronized boolean withdraw() {
     return super.withdraw();
   }

   public synchronized boolean deposite() {
      return super.deposite();
   }
}
  1. 包装类并同步对包装对象的访问:
public class AccountWrapper {
    private final Account realAcount;

    public AccountWrapper(Account realAccount) {
       this.realAccount = realAccount;
    }

    public synchronized boolean withdraw()
    {
       return realAccount.withdraw();
    }

    public synchronized boolean deposite()
    {
        return realAccount.deposite();
    }
}

现在这两种方法都可以通过多种方式完成(像我展示的那样手动),自动生成(归结为上述方法之一,由 CGLIB(字节代码生成库)等库“自动”完成),甚至使用 AOP(面向方面​​的编程)。

另一个注意事项是,可以在方法内部创建一个锁并在其上同步,而不是使用单词 synchronized

当然,如果 Account 类具有共享状态 - 数据字段实际上被 withdrawdeposite 更改和访问,那么这一切都是有意义的> 方法。否则你真的不需要同步任何东西。

关于java - 如何使方法线程安全,即使我忘记在不更改文件的情况下在方法或 block 级别添加同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59948283/

相关文章:

java.nio.file.Path 与 sun.nio.fs.UnixPath

适用于 Google 钱包的 Java Eclipse Google App Engine 教程

java - Java 中的可中断网络 I/O

java - 线程问题

java - 在两个线程和主程序之间共享一个对象

java - 使用synchronized关键字和join()的输出差异

java - Servlet 单元测试

java - liquibase 变更日志文件未从默认值更新

使用 curses.h 库的光标跳转

java - 并发访问 TreeSet 似乎不起作用