Java Spring Bean中的实例变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18042338/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:00:49  来源:igfitidea点击:

Instance variable in Java Spring Bean

javamultithreadingspringthread-safetyheap

提问by ?eref Acet

I'm developing a Java Spring MVC project and i hesitate using instance variable in Java Spring Bean.I want to ask some question about this subject.

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

I used a instance variable in my Java Spring Bean and its type is String.

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

private String abc = "hell";

As we know , Java Spring default scope is Singleton and they are constructed at the startup time of the project. .It is single instance and my instance variable must be thread-safe.

我们知道,Java Spring 默认作用域是 Singleton,它们是在项目启动时构建的。.它是单实例,我的实例变量必须是线程安全的。

I used this variable "abc" in the methods of the beans and when they are reached by multiple threads will it damage the consistency of data each thread?

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

For an example , Thread 1 reach the bean and take the abc variable changed it as "hello".On that time , Thread 1 reference to abc variable point "hell" or "hello"? I'm confused at this topic.

例如,线程1到达bean并取abc变量将其改为“hello”。此时,线程1对abc变量的引用指向“hell”还是“hello”?我对这个话题感到困惑。

I make the String abc variable to ThreadLocalobject to provide each thread holds their own abc variable.But i have read that using ThreadLocalobjects occurs memory leakage in the Tomcat.After 7.0 version of Tomcat it is said that it is fixed.

我将字符串 abc 变量设置为ThreadLocal对象,以提供每个线程持有自己的 abc 变量。但是我读到使用ThreadLocal对象会在 Tomcat 中发生内存泄漏。在 Tomcat 7.0 版本之后,据说它已修复。

Because each thread holds their own variable, and when their job is finished they return the thread pool which is managed by container.But,returning the pool , ThreadLocal object is not destroyed and they cause memory leakage.

因为每个线程都有自己的变量,当他们的工作完成时,他们返回由容器管理的线程池。但是,返回池,ThreadLocal 对象没有被破坏,它们会导致内存泄漏。

Moreover, String object is immutable so in theorical view does it cause the multi-threaded problem ??

而且,String 对象是不可变的,所以从理论上讲它会导致多线程问题吗??

is each thread holds their String variable on its own? For example, Thread 1 triggers and then start the method invocation , and create seperate String variable "abc" and Thread 2 triggers then it creates new String variable "abc" and do they damage "abc" variable each other?

每个线程是否都拥有自己的 String 变量?例如,线程 1 触发然后启动方法调用,并创建单独的字符串变量“abc”和线程 2 触发然后它创建新的字符串变量“abc”,它们是否会损坏“abc”变量?

I really wonder this concept of usage and eager to learn the answers.

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

采纳答案by Boris the Spider

I will try to address your questions separately.

我将尝试分别解决您的问题。

I used this variable abcin the methods of the beans and when they are reached by multiple threads will it damage the consistency of data each thread?

abc在 bean 的方法中使用了这个变量,当它们被多个线程访问时,它会破坏每个线程的数据一致性吗?

The short answer to this question is yes. If you wrote a different value for abcin one Threadit may or may notbe seen from another thread. This is the reason the volatilekeyword was introduced.

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

I you want to have mutablesingleton beans in Springthen you need be careful with synchronization and use of volatile.

如果你想拥有可变的单例 bean,Spring那么你需要小心同步和使用volatile.

The data will not be "corrupted" because, as you point out, Stringis immutable. But one thread may not see that another has changed the value of abc.

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

So you have a variable abc;

所以你有一个变量abc

  1. abc= "Hi."
  2. thread 1 reads abcas "Hi.".
  3. thread 1 changes abcby writing to the reference: abc="Hello."
  4. thread 2 reads abc, it is unclear whether abcreads "Hi." or "Hello.".
  1. abc=“你好。”
  2. 线程 1 读abc作“嗨。”。
  3. 线程 1abc通过写入引用来更改:abc="Hello."
  4. 线程 2 为abc,不清楚是否abc为“嗨”。或“你好。”。

I make the String abc variable to ThreadLocal object to provide each thread holds their own abc variable

我将 String abc 变量设置为 ThreadLocal 对象,以提供每个线程都拥有自己的 abc 变量

ThreadLocalis used to have each thread be given a different instance of a variable. This is often used to tying state to a thread in a web server as web servers use a thread pre request model.

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

Tomcat 7 does notfix ThreadLocalleak issues. If you do not remove the variable you have set from a thread then it willcause a leak. Or even worse a request will get items from the context of another request. This happens when a thread is checked into the pool with context left in its ThreadLocaland then is checked out by another request.

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

Tomcat 7 tires to detect these issues and swap out threads to drop their ThreadLocalvariables. This is expensive and can be avoided by using ThreadLocalproperly.

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

You need to clear ThreadLocalvariables in a servlet filter.

您需要清除ThreadLocalservlet 过滤器中的变量。

So:

所以:

If you have a variable abcthat you want to write to in one thread and for that change not to been seenin other threads then you can use a ThreadLocal, but you need to be very careful to clear state after each request.

如果您abc想在一个线程中写入一个变量,并且要在其他线程中看不到该更改那么您可以使用 a ThreadLocal,但您需要非常小心地在每个请求后清除状态。

If you have a variable abcthat yo want to write to in one thread and for that change to be seenin other threads then you can use a singleton bean with a volatilevariable.

如果您abc想在一个线程中写入一个变量,并且要在其他线程中看到该更改那么您可以使用带有volatile变量的单例 bean 。

回答by Vikas V

I guess in your case if you define the scope of your bean which has your instance variables as Singletonthat should do.

我猜在你的情况下,如果你定义你的 bean 的范围,Singleton它应该有你的实例变量。

As per Spring reference document, below is the definition for Singleton scoped bean.

根据Spring 参考文档,以下是 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.

Singletonis the Default scope that your bean will be put into if you don't specify.

Singleton如果您不指定,则是您的 bean 将被放入的默认范围。

Also, below statement should be kept in mind, if you try to handle your case using Spring's bean scope approach.

此外,如果您尝试使用 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.