Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I always make my java-code thread-safe, or for performance-reasons do it only when needed?

If I create classes, that are used at the moment only in a single thread, should I make them thread-safe, even if I don't need that at the moment? It could be happen, that I later use this class in multiple threads, and at that time I could get race conditions and may have a hard time to find them if I didn't made the class thread-safe in the first place. Or should I make the class not thread-safe, for better performance? But premature optimization is evil.

Differently asked: Should I make my classes thread-safe if needed (if used in multiple threads, otherwise not) or should I optimize this issue then needed (if I see that the synchronization eats up an important part of processing time)?

If I choose one of the both ways, are there methods to reduce the disadvantages? Or exists a third possibility, that I should use?

EDIT: I give the reason this question came up to my mind. At our company we have written a very simple user-management that writes the data into property-files. I used it in a web-app and after some work on it I got strange errors, that the user-management forgot about properties of users(including name and password) and roles. That was very annoying but not consistently reproducible, so I think it was race condition. Since I synchronized all methods reading and writing from/on disk, the problem disappeared. So I thought, that I probably could have been avoided all the hassle, if we had written the class with synchronization in the first place?

EDIT 2: As I look over the tips of Pragmatic Programmer, I saw tip #41: Always Design for Concurrency. This doesn't say that all code should be thread-safe, but it says the design should have the concurrency in mind.

like image 462
Mnementh Avatar asked Oct 24 '08 16:10

Mnementh


People also ask

Why do we need thread-safety in Java?

When multiple threads are working on the same data, and the value of our data is changing, that scenario is not thread-safe and we will get inconsistent results. When a thread is already working on an object and preventing another thread on working on the same object, this process is called Thread-Safety.

What happens if code is not thread-safe?

Conditionally safe: Different threads can access different objects simultaneously, and access to shared data is protected from race conditions. Not thread safe: Data structures should not be accessed simultaneously by different threads.

How does multithreading help Java in its performance?

1) It doesn't block the user because threads are independent and you can perform multiple operations at the same time. 2) You can perform many operations together, so it saves time. 3) Threads are independent, so it doesn't affect other threads if an exception occurs in a single thread.

What are the reasons for using multithreading Why would a thread ever want to call yield?

If in case there are no waiting threads or if all the waiting threads have low priority then the same thread will continue its execution. The advantage of yield() method is to get a chance to execute other waiting threads so if our current thread takes more time to execute and allocate processor to other threads.


2 Answers

I used to try to make everything thread-safe - then I realised that the very meaning of "thread-safe" depends on the usage. You often just can't predict that usage, and the caller will have to take action anyway to use it in a thread-safe way.

These days I write almost everything assuming single threading, and put threading knowledge in the select few places where it matters.

Having said that, I do also (where appropriate) create immutable types, which are naturally amenable to multi-threading - as well as being easier to reason about in general.

like image 130
Jon Skeet Avatar answered Sep 23 '22 10:09

Jon Skeet


Start from the data. Decide which data is explicitly shared and protect it. If at all possible, encapsulate the locking with the data. Use pre-existing thread-safe concurrent collections.

Whenever possible, use immutable objects. Make attributes final, set their values in the constructors. If you need to "change" the data consider returning a new instance. Immutable objects don't need locking.

For objects that are not shared or thread-confined, do not spend time making them thread-safe.

Document the expectations in the code. The JCIP annotations are the best pre-defined choice available.

like image 37
Alex Miller Avatar answered Sep 23 '22 10:09

Alex Miller