RestTemplate线程安全吗?

Rae*_*ald 59 java rest spring thread-safety

Spring是否是RestTemplate线程安全的?那是

  • RestTemplate多个连接可以安全共享的策略对象.要么
  • 是一个RestTemplate连接对象(如数据库连接),在使用时无法共享,并且需要为每个连接重新创建或池化.

Rae*_*ald 80

RestTemplate 线程安全(强调添加):

从概念上讲,它是非常相似的JdbcTemplate,JmsTemplate和Spring框架和其他投资项目中发现的各种其他模板.这意味着,例如,RestTemplate一旦构造就是线程安全的


RestTemplate类的对象不会更改任何状态信息来处理HTTP:类是策略设计模式的实例,而不是像连接对象.在没有状态信息的情况下,如果共享RestTemplate对象,则不可能有不同的线程破坏或竞争状态信息.这就是线程可以共享这些对象的原因.

如果检查源代码,RestTemplate您将看到它在构造对象后不使用synchronized方法或volatile字段来提供线程安全性.因此,它是不是安全的修改RestTemplate施工后的对象.特别是,添加消息转换器是不安全的.

要为其提供消息转换器列表,您必须执行以下操作之一:

  • 使用RestTemplate(List<HttpMessageConverter<?>> messageConverters)构造函数.作为messageConvertersis 的内部列表final,这将安全地发布消息转换器列表.
  • 使用setMessageConverters(List<HttpMessageConverter<?>> messageConverters)突变然后安全地-发布改变的RestTemplate对象.使用具有此功能的Spring bean定义<property name="messageConverters"><list>...,因为在大多数实际用例中,设置容器的线程将安全地发布 bean .
  • List.add在返回的引用上使用getMessageConverters(),然后安全地发布更改的RestTemplate对象.但是,该文档RestTemplate未明确声明它返回可用于更改消息转换器列表的引用.当前的实现确实如此,但可能会更改实现以返回Collections.unmodifiableList列表的副本或副本.所以最好不要这样改变它.

需要注意的是第一种情况是构建对象时建立的消息转换器的唯一手段,因此它正确的说,它"是线程安全的,一旦构成".

该类是Spring Framework的一部分,因此在几乎所有实际情况中,类的对象将被设置为Spring Application Context的一部分,使用第一个(使用构造函数的依赖注入)或第二个(使用setter的依赖注入)方法,因此将保证安全地发布到多个线程.

  • 它不仅是线程安全的,而且它的创建似乎很昂贵.我最近在tomcat上运行了主要的性能问题,因为RestTemplate的初始化导致了类加载器锁争用. (5认同)
  • “一旦构造线程安全”似乎意味着“只要你不改变它的状态就是线程安全的”,这是真的,因为 _any_ 对象是线程安全的,只要它的状态不改变。 (4认同)
  • 我不认为它的线程安全。它使用消息转换器,您可以在运行时从两个不同的线程添加消息转换器。它会在执行 restTemplate.exchange() 调用时抛出并发修改异常,因为它会遍历此消息转换器。 (3认同)
  • @BorisTreukhov 我还注意到在调试时性能受到影响,所以我用谷歌搜索并找到了这个。 (3认同)
  • @comiventor 如果您不使用自定义 messageConverters,则可以使用 RestTemplate 的一个实例。否则,通过构造函数注入 messageConverters - 也是线程安全的。 (2认同)

归档时间:

查看次数:

32028 次

最近记录:

6 年,1 月 前