Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread safety of the plus operator for Strings, optimizations included

This post says that a += b is the equivalent of

a = new StringBuilder()
    .append(a)
    .append(b)
    .toString();

Let's say I have this code:

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);
    }
}

Assume that beginmt runs multiple times simultaneously (with thread numbers 1 to 15500) on a single instance of MultiThreading class. Could there be instances such that it could print the following i.e. some thread numbers are lost and some numbers are doubled?

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
...

Edit:

Will it be safe to say that the + operator won't get into some unsafe publication issue? I'm thinking the StringBuilder could be optimized into something that resembles an instance variable in which case it could be unsafely published.

Edit 2:

As far as the JLS, the abovementioned post, and a similar class file for the above code are checked, the StringBuilders to be used seem to have to get contained within different stackframes. However, I'd still like to check whether some form of aggressive optimization could cause the StringBuilders to be replaced by a centralized StringBuilder in some way. This sounds possible as it sounds logical for optimizers to optimize when it predicts that an object is just implemented in a non-constant way when in fact such object could be constant.

Found stringopts.cpp but haven't found the time yet to fully check it. I'm hopefully looking for answers involving details of this source file.

Edit 3:

I'm still looking for answers that include code on aggressive inlining for mutable objects.

like image 993
damat-perdigannat Avatar asked Aug 22 '14 08:08

damat-perdigannat


2 Answers

No, there is no state that's being shared between different threads so the situation you described can not happen.

If instead st was a member variable of that class, instead of being passed as an argument, and was incremented - that's a different story.

How it works now is that st will be put on the execution stack, each thread has it's own execution stack and they don't share stuff from there. Therefore each thread has it's own value of st. When it's a member variable of a class it's in memory (single value) and all threads would try to use it (the same one).

@Edit: well I guess it is possible if you call the method several times with the same value :-))

like image 192
Mateusz Dymczyk Avatar answered Sep 22 '22 16:09

Mateusz Dymczyk


Could there be instances such that it could print the following i.e. some thread numbers are lost and some numbers are doubled?

st is a method local variable, also st doesn't escape the method's scope so it is thread-safe. So, multithreading will have no effect on st . The messages can be printed out of order depending on which thread runs the method at what time.

like image 39
TheLostMind Avatar answered Sep 21 '22 16:09

TheLostMind