字符串的plus运算符的线程安全性,包括优化

新郎

这篇文章说,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,上面提到的文章以及上面代码的类似类文件,要使用的StringBuilders似乎必须包含在不同的堆栈框架中。但是,我仍然想检查某种形式的积极优化是否可能以某种方式导致StringBuilder被集中式StringBuilder取代。这听起来可能是可行的,因为当优化程序预测某个对象只是以非恒定方式实现时(实际上实际上该对象可能是恒定的),这对于优化器而言是合乎逻辑的。

找到了stringopts.cpp,但尚未找到完全检查它的时间。希望我能找到涉及此源文件详细信息的答案。

编辑3:

我仍在寻找包含针对可变对象的主动内联代码的答案。

视频数据库

每个线程将始终具有单独的StringBuilder实例。当线程不共享实例时,线程安全性不是问题。

因此,以下简单方法...

public class MyThreadSafeClass
{
  public String myMethod(String field1, String field2, String field3)
  {
     return field1 + field2 + field3;
  }
}

...将被编译为使用本地StringBuilder。

public class MyThreadSafeClass
{
  public String myMethod(String field1, String field2, String field3)
  {
     return new StringBuilder(field1).append(field2).append(field3).toString();
  }
}

每次输入方法时,StringBuilder都会创建一个新实例。该实例仅在该线程的范围内使用。

您是正确的,但是StringBuilders并不总是线程安全的。(请参阅下文)如果多个线程开始调用该saveEvent方法,则它们可能同时在使用构建器。

public class History
{
  // thread-safety issues !!!! 
  // In fact, here you should use a StringBuffer or some locking.
  private StringBuilder historyBuilder = new StringBuilder();

  public void saveEvent(String event)
  {
     historyBuilder.append(event).append('\n');
  }

  public String getHistoryString()
  {
     return historyBuilder.toString();
  }
}

但是编译器优化不会创建这种构造。StringBuilder始终创建并只在同一个线程中使用。

我们可以尝试使事情变得更复杂(静态字段,多个类加载器等),但总是会再次出现,每个StringBuilder实例仅由1个线程创建和使用。

编辑:

可能有用的知识:这种优化发生在字节码的生成过程中稍后在JIT编译过程中还有其他优化,但是这种优化不是其中之一。但是,JIT编译器确实会对最终性能产生重要影响

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章