1

I have been trying to grasp concept of multi-threading and confused about the below code:

class MyClass{ private StringBuilder content = new StringBuilder(); public void setContent(){ content.append("Some String"); content.append("more String"); } public String getContent(){ return content.toString(); } } 

My understanding is that MyClass cannot be made thread safe just by synchronizing its setter and getter methods. Because while creating MyClass object ,content reference may have improper object initialization. To make proper initialization the content should be final. Can anyone help me to clarify it?

5
  • Make the class singleton and make setters and getters synchronized. Commented Dec 18, 2018 at 9:10
  • 1
    That would definitely be another approach that how to design the class. What I want to get is correct understanding that , is this class thread safe or not. As per my opinion it is not. Commented Dec 18, 2018 at 9:19
  • Yes. content should be final in order to guarantee all threads see its initialized value. Commented Dec 18, 2018 at 9:22
  • currently the class is not thread safe. Commented Dec 18, 2018 at 9:24
  • Thank you so much @Andy Turner. Commented Dec 18, 2018 at 9:24

3 Answers 3

1

My understanding is that MyClass cannot be made thread safe just by synchronizing its setter and getter methods.

That is not correct.

Provided that the reference for a MyClass instance is safely published to all threads that use it, then synchronized getters and setters will see the correct initial state for the object.

If you declare content (and any other fields) to be final you can dispense with the requirement for safe publication. However, since this is not an immutable class, it will still be necessary for the getter and setter to synchronize.


The special semantics for final fields (as described in JLS 17.5) allow truly immutable objects to be thread-safe without any synchronization overheads. But these semantics are not directly applicable in your example because the "setter" is mutating the object.


Incidentally, if content had type StringBuffer rather than StringBuilder AND the variable was final. The result would be "mostly" thread-safe without synchronized. That is because StringBuilder is thread safe for these operations. The only catch is that your "setter" is calling append twice. Without a synchronized, it would be possible for a getter to see the intermediate state of the buffer.

Sign up to request clarification or add additional context in comments.

1 Comment

I disagree. Changing the contents of content changes the state of MyClass from the perspective of something calling getContent(). It is a mutable class. But that's not the point I am trying to make. Adding the final removes the need for safe publication. That may or may not be important, but it is a difference.
1

Immutability is not always the answer to thread-safety. Lets first examine the potential thread-safety issues in the existing code. The potential problem is when you have two threads (A, and B) accessing the setter method setContent() simultaneously. That would result in having a randomized output String that might look like Some String Some String more String Some String Some String because you have no way to ensure that more String must be added right after Some String.

That logic could be perfectly fine in your application. However, if you still need to ensure that those two append statements are added together, that is when synchronization come in place. In that case, you could synchronize the setter method to ensure that only one thread at a time can access it.

Do not worry about having null StringBuilder because your method will not be accessed without instantiating the MyClassinstance first.

Hope this helps

Comments

0

Immutability and Thread-Safety goes hand in hand , if you are able to make your class Immutable then its said the class will be inherently thread safe , however to achieve same is not easy.

To create immutable class in java, you have to do following steps.

  1. Declare the class as final so it can’t be extended.
  2. Make all fields private so that direct access is not allowed.
  3. Don’t provide setter methods for variables
  4. Make all mutable fields final so that it’s value can be assigned only once.
  5. Initialize all the fields via a constructor performing deep copy.
  6. Perform cloning of objects in the getter methods to return a copy rather than returning the actual object reference.

but do read this https://dzone.com/articles/do-immutability-really-means as this gives a food for thought on immutable classes

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.