A string is immutable which means that once you amend the value its create a new reference and leave the previous reference value as it was.
However, I don't understand when someone arguing :
Strings are thread safe as they are immutable
Consider below code:
private String str = "1";
ExecutorService executorService = Executors.newFixedThreadPool(10);
IntStream.range(0, 1000).forEach((i)-> executorService.submit(()-> {
str = str +"1";
}));
executorService.awaitTermination(10, TimeUnit.SECONDS);
System.out.println(str.length());
If it was thread safe then it should print 1001 while it is always print less than expected value.
I understand the above code will create 1001 immutable references which each one is thread-safe on its own, but as a developer, still can not using something immutable and expect the end-result would be thread safe.
IMHO, immutability is not guaranteed thread safety.
Could someone please explain to me how a String is threaded safe?
Update:
Thanks for your answers, I understand that each string could be thread safe, but my point was, there is no direct relationship between thread safety and immutability when you use them in other methods.
for example, an immutable object can be used in the stateful object and ended with the non-thread safe result and also a mutable object could be used in a synchronised method and ended up with a thread-safe result.
Its important to know how memory works in programming languages. The variable str is not a String Object, like you would think. But it is instead a reference to a String Object, with some address.
Modifying what str points to, does not modify the string that it points to. In fact what happens is something like this:
We have a pool of memory, in our pool is three strings. Each string has an address that allows us to find it.
We have a variable that is pointing to each one, we will call them a,b, and c.
If we said: System.out.println(a); Java would print Hello. But a is not "Hello". Instead a is something that contains 0x449345. The computer then goes: "Okay, i'll go take what is at 0x449345 and print it out." When it goes and looks at that address, it finds the string "Hello".
However, if you said: a = "NEW STRING"; a would not point to any of our previous addresses. Instead a new address is created and "NEW STRING" is placed inside that memory location.
This is also how Garbage Collection works in Java. Once you set a equal to "NEW STRING" it no longer points to 0x449345, this tells the garbage collector that that object is safe to remove. This is how your program cleans up after itself, and does not eat up tons of RAM.
Because of this, the reference that points to a string, is not thread safe but the actual object IS! Any immutable object is thead safe, because you CANNOT modify that object at all, you can only modify what your variable points to. You would have to point to a different object entirely to "modify", your immutable object.
I think this can summarized as follows:
String objects are thread-safe. (They are thread safe because String objects are immutable, but the why is not directly relevant to your example.)final shared2 variables are not thread-safe, irrespective of the type of the variable.Your example does str = str + 1;. That combines operations on String objects with operations on an unsynchronized shared variable (str). It is not thread-safe because of the latter.
1 - More precisely, operations where there is no happens before relationship between writes and reads to guarantee required memory visibility properties, and there is no locking to guarantee required atomicity properties. ("Required" means required for correctness of the algorithm ...)
2 - Shared means visible to and used by more than one thread. If a variable is only visible to or used by one thread, it is said to be thread-confined and it is effectively not shared.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With