这段代码中的 StringBuilder 变量线程安全吗?
考虑下面的 struts Action
类,我在其中的执行方法中使用 StringBuilder
变量。我的问题:变量 sb 是否是线程安全的?
public DemoAction extends Action
{
......
public ActionForward execute(.....)
{
StringBuilder sb = new StringBuilder();
}
}
如果在execute() 之外声明相同的变量sb 会怎样?请记住,WebContainer 中只有一个 DemoAction 对象。?
Consider the below struts Action
class in which, I am using a StringBuilder
variable inside the execute method. My question: Is the variable sb
threadsafe or not?
public DemoAction extends Action
{
......
public ActionForward execute(.....)
{
StringBuilder sb = new StringBuilder();
}
}
What if the same variable sb declared outside the execute(). Remember there will be only one object for DemoAction in WebContainer.?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
局部变量是线程安全的,只要没有其他线程以某种方式获取对同一字符串生成器实例的引用,它就是线程安全的。
Local variables are thread safe, as long as no other thread somehow gets a reference to the same string builder instance, it’s thread safe.
它是线程安全的,因为您只在方法的范围内创建和使用它,因此引用将存储在每个线程本地的堆栈空间中
It is threadsafe because you only create and use it in the scope of the method so reference will be stored in stack space which is local for each thread
是的,局部变量本质上是线程安全的。每个线程都有自己的副本。
Yes, local variables are inherently thread-safe. Every thread gets its own copy.
来自 Java 6
StringBuilder
Javadoc:这意味着该类不是线程安全的,您应该更喜欢
StringBuffer
您知道该变量将被并发访问。但是,在这种情况下,您可以保证您的
StringBuilder
只能从一个线程访问,因为它是局部变量而不是实例变量。有关说明,请参阅问题“线程安全和局部变量”。From the Java 6
StringBuilder
Javadoc:This means that the class is not threadsafe, and you should prefer
StringBuffer
where you know the variable will be accessed concurrently.However, you can guarantee in this case that your
StringBuilder
will be accessed only from one thread, because it is local variable rather than an instance variable. See the question 'Thread safety and local variables' for an explanation.这是安全的。该变量是
execute()
方法的本地变量,并且在每次调用该方法时都会创建,因此在多线程环境中,每个线程都可以拥有自己的、单独的sb
变量副本。It is safe. This variable is local to
execute()
method and is created every time this method is called, so in multithread environment every thread can have its own, separate copy ofsb
variable.StringBuilder 不是线程安全的,但只要您从单个线程使用它,就不必担心它。即使您从两个线程进行访问,您也可以通过用同步块封闭关键部分来轻松使其线程安全,例如,
如果整个方法是关键部分,您可以在该方法上说同步
注意我显式编写了两个附加语句来演示仅使用线程安全的 StringBuffer 不会使代码线程安全。如果您使用 StringBuffer 运行两个线程,则每个追加可能会同步,但仍然有可能发生竞争条件。
因此,两个写入“hello”和“world”的线程可能会导致输出“您输入了您输入了helloworld”,因为每个附加都受到保护,而不是整个操作。
使用同步类的效率也较低。例如,在上面的示例中,对追加的两次调用都是同步的,因此除了竞争条件之外,我还必须锁定对象两次,而不是使用非同步类锁定对象一次。
StringBuilder isn't thread safe, but as long as you use it from a single thread you don't have to worry about it. Even if you do access from two threads you can easily make it thread safe by enclosing the critical section with a synchronized block, e.g.
If the entire method is the critical section you can say synchronized on the method
Note I explicitly wrote two append statements to demonstrate that just using thread safe StringBuffer wouldn't make code thread safe. If you ran two threads with a StringBuffer then each append might be synchronized but it would still be possible for race conditions to occur.
So two threads writing "hello" and "world" might result in the output "You entered You entered helloworld" because each append is protected not the whole action.
Using synchronized classes are also less efficient. For example in the above example, both calls to append are synchronized so in addition to a race condition I have to lock the object twice compared to once with the non-synchronized class.
来自规范:
但正如 Konrad Rudolph 指出的,在你的情况下它是一个局部变量,所以你应该没问题
From the spec:
But as Konrad Rudolph pointed out, in your case it's a local variable so you should be fine