Search code examples
javamultithreadingthread-safetythread-synchronization

threads accessing non-synchronised methods in Java


can I ask to explain me how threads and synchronisation works in Java?

I want to write a high-performance application. Inside this application, I read a data from files into some nested classes, which are basically a nut-shell around HashMap.

After the data reading is finished, I start threads which need to go through the data and perform different checks on it. However, threads never change the data!

If I can guarantee (or at least try to guarantee;) that my threads never change the data, can I use them calling non-synchronised methods of objects containing data?

If multiple threads access the non-synchronised method, which does not change any class field, but has some internal variables, is it safe?

artificial example:

public class Data{
// this hash map is filled before I start threads
protected Map<Integer, Spike> allSpikes = new HashMap<Integer, Spike>();

public HashMap returnBigSpikes(){
     Map<Integer, Spike> bigSpikes = new HashMap<Integer, Spike>();

     for (Integer i: allSpikes.keySet()){
         if (allSpikes.get(i).spikeSize > 100){
         bigSpikes.put(i,allSpikes.get(i));
         }
     }

     return bigSpikes;
}
}

Is it safe to call a NON-synchronised method returnBigSpikes() from threads?

I understand now that such use-cases are potentially very dangerous, because it's hard to control, that data (e.g., returned bigSpikes) will not be modified. But I have already implemented and tested it like this and want to know if I can use results of my application now, and change the architecture later...

What happens if I make the methods synchronised? Will be the application slowed down to 1 CPU performance? If so, how can I design it correctly and keep the performance?

(I read about 20-40 Gb of data (log messages) into the main memory and then run threads, which need to go through the all data to find some correlation in it; each thread becomes only a part of messages to analyse; but for the analysis, the thread should compare each message from its part with many other messages from data; that's why I first decided to allow threads to read data without synchronisation).

Thank You very much in advance.


Solution

  • If allSpikes is populated before all the threads start, you could make sure it isn't changed later by saving it as an unmodifiable map.

    Assuming Spike is immutable, your method would then be perfectly safe to use concurrently.