No, it does not have to have any locking constructs.
Any pure method will function just fine in a multithreaded environment.
By "pure" I mean a method that:
- The function always evaluates the same result value given the same argument value(s). The function result value cannot depend on any hidden information or state that may change as program execution proceeds or between different executions of the program, nor can it depend on any external input from I/O devices.
- Evaluation of the result does not cause any semantically observable side effect or output, such as mutation of mutable objects or output to I/O devices.
(source: Wikipedia: Pure Function)
In your case, string concatenation by itself is fine in a multithreaded environment and does not need any locking constructs.
However, if you're concatenating strings that you read from fields or properties that can be changed by other threads, then you will need locking or similar to ensure the stability of your system, but the example code in your question, no.