2013-08-04 78 views
4

我正在开发一个Java Spring MVC项目,并且我很犹豫在Java Spring Bean中使用实例变量。我想问一些关于这个主题的问题。Java Spring Bean中的实例变量

我在我的Java Spring Bean中使用了一个实例变量,它的类型是String。

private String abc = "hell"; 

正如我们所知,Java Spring默认范围是Singleton,它们是在项目启动时构建的。它是单实例,我的实例变量必须是线程安全的。

我在bean的方法中使用了这个变量“abc”,当它们被多个线程到达时,它会损害每个线程数据的一致性吗?

例如,线程1到达bean并将abc变量改为“hello”。那时,线程1引用abc变量point“hell”或“hello”?我很困惑这个话题。

我使字符串ABC变量ThreadLocal目的是提供每个线程持有自己的ABC variable.But我已阅读,使用ThreadLocal对象时出现据说它是固定在Tomcat.After 7.0版的Tomcat存储器泄漏。

因为每个线程拥有自己的变量,当他们回到这是由container.But管理线程池,恢复池的作业完成,ThreadLocal的对象不被破坏,它们造成内存泄漏。

此外,String对象是不可变的,所以在理论视图中它是否会导致多线程问题?

是每个线程都拥有自己的字符串变量吗?例如,线程1触发并启动方法调用,并创建单独的字符串变量“abc”和线程2触发器,然后创建新的字符串变量“abc”,并相互损害“abc”变量?

我真的很想知道这个用法的概念,并且很想学习答案。

回答

4

我会尝试单独解决您的问题。

我用在豆的方法此变量abc并且当它们 由多个线程达到会损伤数据 每个线程的一致性?

简短的回答这个问题是肯定的。如果您为abc写入了一个Thread的不同值,则可能会或可能不会从另一个线程看到。这就是引入volatile关键字的原因。

我要在Spring可变单豆类,那么你需要小心的同步和使用volatile

数据将不会“损坏”,因为正如您所指出的,String是不可变的。但有一个线程可能看不到另一个线程已更改abc的值。

所以你有一个变量abc;

  1. abc =“嗨。”
  2. 线程1将abc写为“Hi。”。
  3. 线程1通过写入信号的变化abcabc="Hello."
  4. 线程2读取abc,目前还不清楚是否abc读“你好。”或“你好。”。

我使ABC的字符串变量ThreadLocal的目的是提供每个线程拥有自己的ABC变量

ThreadLocal用来让每个线程被赋予一个变量的不同实例。这通常用于将状态绑定到Web服务器中的线程,因为Web服务器使用线程预先请求模型。

Tomcat 7 不会修复ThreadLocal泄漏问题。如果你不删除你从线程设置的变量,那么它会导致泄漏。或者更糟糕的是,请求会从另一个请求的上下文中获取项目。当一个线程被检入池并且其上下文在ThreadLocal中,然后被另一个请求检出时,就会发生这种情况。

Tomcat 7轮胎检测到这些问题,并换出线程来删除它们的ThreadLocal变量。这很昂贵,可以通过正确使用ThreadLocal来避免。

您需要清除一个servlet过滤器中的ThreadLocal变量。

所以:

如果你有你想要写在一个线程并不会被视为在其他线程这种变化那么你可以使用一个ThreadLocal变量abc,但你需要每次请求后都要非常小心地清除状态。

如果你有一个变量abc哟想写在一个线程,该更改待观察在其他线程,那么你可以使用一个singleton bean与volatile变量。

+0

我在一个方法中使用了ThreadLocal对象,并且此方法由JSP调用。方法的第一行从方法参数中取得ThreadLocal对象集的值。因此,“但是您需要非常小心地在每次请求后清除状态。”我提供这个声明,如果我理解正确,那么没问题。如果发生内存泄漏,我将为servlet过滤器设置ThreadLocal对象。我是对吧? –

1

我想你的情况,如果你定义你的bean的范围,它的实例变量为Singleton应该做的。

根据Spring reference document,下面是Singleton作用域bean的定义。

To put it another way, when you define a bean definition and it is scoped as a singleton, 
the Spring IoC container creates exactly one instance of the object defined by that bean 
definition. This single instance is stored in a cache of such singleton beans, and all 
subsequent requests and references for that named bean return the cached object. 

Singleton是默认的范围,你的bean将投产,如果你不指定。

此外,下面的语句应该牢记,如果您尝试使用Spring的bean作用域的方式来处理您的案件。

This approach is powerful and flexible in that you can choose the scope of the objects 
you create through configuration instead of having to bake in the scope of an object at  
the Java class level. 
+0

这是如何回答OPs线程安全问题的? –

+0

@BoristheSpider与定义单个bean定义到任何数量的对象实例的'prototype'不同,'Singleton' scope将单个bean定义的范围限定为每个Spring IoC容器的单个对象实例。我正在用范围创建的_object instances_的数量。 –

+0

首先感谢您的回复Vikas V. 例如,线程1到达bean,并将abc变量改为“hello”。那时,线程2引用abc变量point“hell”或“你好”?我很困惑这个话题。 –