当前位置: 首页 > 面试题库 >

使用Spring进行线程安全的无状态设计

章哲茂
2023-03-14
问题内容

我假设如果实例变量是由spring
IOC管理的,并且是单例的,则设计可以被称为无状态和线程安全的,因此这种设计可以扩展到集群服务器。我的假设是否正确?概述如下?

@Repository("myDao")
public class MyDao implements Dao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Value("${sqlFoo}")
    private String foo;

    @Override
    public Integer getMyInt(String str) {
      return jdbcTemplate.queryForInt(foo, str);
    }

然后将其注入:

@Service("myService")
public class MyServiceImpl {

    @Resource(name = "myDao")
    Dao dao;

    @Override
    @Transactional(readOnly = true)
    public int getScore(String str) {
      return dao.getMyInt(str);
    }
}

问题答案:

Spring bean不是无状态的,因为它们具有状态(字段)。从技术上讲,它们甚至不是一成不变的,因为您可以随时更改注入的字段。

但是,您可以通过使用final字段和构造函数注入轻松地使Spring
bean不可变。从可伸缩性的角度来看,这种状态也不成问题。如果您的bean包含随时间变化的可变值,那么这是集群时的主要问题。但是在Spring服务中,通常仅包含在引导时注入的依赖项。因此,它们实际上是无状态且不可变的。

运行相同的Spring应用程序的服务器数量无关紧要-Bean和依赖项本身是安全的。 但是, 如果您的Spring bean包含计数器,缓存,可变映射等-
您需要考虑一下它们。



 类似资料:
  • 我构建了这个“节流”任务运行器,它在HashMap中收集一些数据,同时(每分钟)将数据“带走”并清除HashMap。在我的测试中,我注意到executor部分可以停止,并且永远不会再次清除HashMap。我假设这是因为我所做的HashMap修改不是线程安全的,它在内部崩溃,没有恢复。我正在两个线程中修改HashMap。有人能告诉我如何优化HashMap修改的正确方向吗。

  • 我有一个简单的静态日志记录类。但是,它肯定不是线程安全的,因为每个调用都试图写入同一个文件。我得到了这些例外情况: 什么是最好的方法使它的线程安全? 作为一个日志记录函数,我希望能够从代码的许多不同部分访问它(因此,我选择它为静态的原因)。然而,我想要使它成为线程安全的,我总是必须向它传递一个公共对象来lock(),我认为这违背了静态函数的目的。还是事实并非如此?

  • 问题内容: 鉴于以下多态: 我们如何在没有昂贵的getInstance()方法同步和双重检查锁定争议的情况下使它保持线程安全和懒惰?这里提到了单例的有效方法,但似乎并没有扩展到多例。 问题答案: 使用Java 8,它甚至可以更简单:

  • 下面是一个解释线程安全性的示例方法: 为了提供线程安全,有几种方法,我更喜欢使用方法。然而 1.我还想知道是否可以通过对必要的变量使用来提供线程安全。如果是,我如何执行此操作? 2.Java中经常使用作为变量和方法参数来提供线程安全性,这是原因之一吗?

  • 我有许多线程处理对象,其中我使用将数据库列映射到对象。 我知道在任何Java中都不是线程安全的。因此,我在中得到了一些不可预测的结果。例如,我在中也看到了。 下面是我的代码: 我的核心池大小约为20这个应用程序的最大约50。这些线程在某个时候可以处理数据库中大约100个交易记录。 使此日期格式化线程安全的最佳方法是什么?我应该使用FastDateFormat直接替换吗? 有没有更好的替代方法来确保

  • 问题内容: 我想将Calendar用于某些静态方法并使用一个静态字段: 现在,我读到java.util.Calendar不是线程安全的。如何使该线程安全(应该是 静态的 )? 问题答案: 如果不是,则不能创建线程安全的东西。在的情况下,即使从中 读取 数据也不是线程安全的,因为它可以更新内部数据结构。 如果有可能,我建议改用Joda Time: 大多数类型是不可变的 不可变类型是线程安全的 无论如