119
class Clstest{

    public static String testStaticMethod(String inFileStr) {
        
        // section 0
        
        // section 1
        
        // do something with inFileStr
        
        // section 2
        
        // section 3
        
        return inFileStr;

    }

}

Let's assume there are five threads are each executing a call to Clstest.testStaticMethod("arg-n") at the same time.

Thread 1 calls Clstest.testStaticMethod("arg-1").

When thread 1 is in the section 1, thread 2 calls Clstest.testStaticMethod("arg-2").

Then what will happen to Thread 1? Will it go to sleep state?

When Thread 1 got the chance will it resume the execution from section 1 where it was paused?

How it happens when there's one Clstest.testStaticMethod and same Clstest.testStaticMethod is shared between all five threads?

Is there any possibility to interchange the inFileStr sent by multiple threads?

vvvvv
  • 25,404
  • 19
  • 49
  • 81
ironwood
  • 8,936
  • 15
  • 65
  • 114

2 Answers2

198

Hans Passant's answer is good. But I thought I would try and explain at a slightly more simple level for anybody who comes across this and is newish to Java. Here goes..

Memory in java is split up into two kinds - the heap and the stacks. The heap is where all the objects live and the stacks are where the threads do their work. Each thread has its own stack and can't access each others stacks. Each thread also has a pointer into the code which points to the bit of code they're currently running.

When a thread starts running a new method it saves the arguments and local variables in that method on its own stack. Some of these values might be pointers to objects on the heap. If two threads are running the same method at the same time they will both have their code pointers pointing at that method and have their own copies of arguments and local variables on their stacks. They will only interfere with each other if the things on their stacks point to the same objects on the heap. In which case all sorts of things might happen. But as Hans points out, Strings are immutable (cannot be changed) so we're safe if this is the only object being "shared".

So many threads can be running the same method. They might not be running at the same time - it depends how many cores you have on your machine as the JVM maps Java threads to OS threads, which are scheduled onto hardware threads. You therefore have little control over the way these threads interleave without using complex synchronisation mechanisms.

Note that sleeping is something a thread does to itself.

selig
  • 4,834
  • 1
  • 20
  • 37
  • 3
    So, in multi-core processor environment there might be multiple threads running same code same time isn't it? And in single processor environment there is only one thread running at a given time. (multiple threads sharing the time among them.) So, when the thread schedular give the chance from current excuting thread (A) to thread (B), how is the thread (A) resume from where it was paused? I mean how does it know the resume point? Is it because of "Each thread also has a pointer into the code which points to the bit of code they're currently running?" as you said? – ironwood Jun 27 '13 at 15:52
  • 6
    You've got it. Just to clarify some points - firstly, how threads are scheduled is outside of Java's control. I'm talking about Sun's Hotspot JVM here. The JVM maps a Java thread to an OS thread and the OS decides which threads to run. As you say, on a single core machine the OS can only run one at a time, but in a multicore machine it may run more than one at once. Secondly, a thread isn't really aware of when it gets paused, the only information it has is it's program pointer (the pointer into the code) and stack, which are saved and restored exactly as they were. – selig Jun 27 '13 at 15:57
  • So, inter-thread interference happens when threads are using variables out of their local scope and, for example, one thread updates variable's value before other thread pulls thats variable (or pointer to the variable) on its own stack? Is that a right understanding? – hariszhr Feb 06 '16 at 05:09
  • 2
    To be slightly more precise... interference can only happen and may happen but will not necessarily happen... when threads share things on the heap (non-local). There are a few different ways interference can happen which depend on the dependencies between different parts of the code. I'm not sure about your example as there are some details missing. Perhaps you are referring to a potential issue where threads A and B both read a shared value and then both update it based on the read value. This is a data race. – selig Feb 10 '16 at 10:28
  • 1
    @selig if I have a class with only instance methods for ex: a service class and It is singleton then I don't need to worry about multiple threads executing the instance methods at a time as the service class does not hold any state where state is present only if class has instance variables. Is my understanding correct? – Yug Singh Oct 23 '18 at 20:34
  • `In Continuation to previous comment` : And even if class has instance variables and they are immutable like String then also no need to worry about multiple threads executing at the same time. – Yug Singh Oct 23 '18 at 20:45
  • @YugSingh If there is no state or if that state is immutable then there is nothing for threads to fight over (you are safe). However, I'm not sure how this is related to the notion of a singleton. Two slight caveats. Firstly, multiple threads could still get in a tangle if there is any synchronisation going on (e.g. deadlock). Secondly, immutable objects need to make sure they don't 'escape their constructors' to be 'safe' ... so don't do weird constructor stuff. – selig Oct 23 '18 at 21:35
  • 1
    @namalfernandolk - so even if I pass a mutable object which was spawned in the thread itself and alter its state in the method it is perfectly thread-safe? – z3r0 Mar 06 '20 at 10:13
68

Will it go to sleep state?

No, running a thread does not affect other threads as long as they don't intentionally synchronize with each other. If you have more than one processor core, all recent machines do, those threads are likely to execute at the exact same time. That gets to be bit less likely when you start 5 threads since your machine might not have enough cores. The operating system is forced to choose between them, giving them each some time to run. The job of the thread scheduler. A thread will then not be in a "sleep" state, it is simply paused and waiting for the thread scheduler to give it a chance to run. It will resume where it was interrupted by the scheduler.

Is there any possibility to interchange the inFileStr sent by multiple threads?

There is no such possibility, threads have their own stack so any method argument and local variable will be unique for each thread. Using a string furthermore guarantees that these threads cannot interfere with each other since strings are immutable.

There's no such guarantee if the argument is a reference to another kind of mutable object. Or if the method itself uses variables that are static or references to objects on the heap. Synchronization is required when a thread modifies the object and another thread reads it. The lock keyword in the C# language is the boilerplate way to implement such required synchronization. The fact that the method is static does not mean such synchronization is never required. Just less likely since you don't have to worry about threads accessing the same object (sharing this).

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536