This post表示 a += b
等价于
a = new StringBuilder()
.append(a)
.append(b)
.toString();
假设我有这段代码:
public class MultiThreadingClass extends SomeThirdPartyClassThatExtendsObject{
public void beginmt(String st) throws IOException {
//st is a thread number
st = new File("c:\\somepath").getCanonicalPath()+"\\"+st;
System.out.println(st);
}
}
假设 beginmt 在 MultiThreading 类的单个实例上同时运行多次(线程号从 1 到 15500)。是否存在这样的实例,它可以打印以下内容,即一些线程编号丢失,一些线程编号加倍?
c:\somepath\2
c:\somepath\1
c:\somepath\1
c:\somepath\4
c:\somepath\5
c:\somepath\6
c:\somepath\7
c:\somepath\8
c:\somepath\8
c:\somepath\10
...
编辑:
可以肯定地说 + 运算符不会陷入一些不安全的发布问题吗?我认为 StringBuilder 可以优化成类似于实例变量的东西,在这种情况下它可能会被不安全地发布。
编辑 2:
就检查 JLS、上述帖子和上述代码的类似类文件而言,要使用的 StringBuilder 似乎必须包含在不同的堆栈框架中。但是,我仍然想检查某种形式的积极优化是否会导致 StringBuilder 以某种方式被集中式 StringBuilder 取代。这听起来是可能的,因为当优化器预测对象只是以非常量方式实现而实际上此类对象可能是常量时,优化器进行优化听起来合乎逻辑。
找到 stringopts.cpp但还没有找到时间来全面检查它。我希望寻找涉及此源文件详细信息的答案。
编辑 3:
我仍在寻找包含可变对象积极内联代码的答案。
最佳答案
不,不同线程之间没有共享状态,因此您描述的情况不会发生。
如果 st 是那个类的成员变量,而不是作为参数传递,而是递增 - 那就是另一回事了。
现在的工作原理是 st 将被放入执行堆栈,每个线程都有自己的执行堆栈,并且它们不共享那里的东西。因此每个线程都有它自己的 st 值。当它是一个类的成员变量时,它在内存中(单值)并且所有线程都会尝试使用它(同一个)。
@Edit:好吧,我想如果您使用相同的值多次调用该方法,是是可能的:-))
关于java - 字符串加号运算符的线程安全,包括优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25442323/