How can multiple threads execute same method in parallel? - java

I stuck on this question while reading this article about how Spring singleton, stateless bean serve multiple requests.
This is the main author point of how it is done:
When the thread request the singleton bean, it is going to refer (with help of reference variable in stack) to the bytecode of singleton bean in heap. So multiple threads can refer singleton bean at the same time. The compiler is going to point to the same bytecode and simply execute it and store method specific values in corresponding blocks in stack separately.
Good article but it missing some crucial details about how exactly bytecode is executed by threads. My undestanding: Each thread has it own stack, stack contains frames, frames contains return values, local variables, operand stack and Current Class Constant Pool Reference. All classes ale loaded to Method Area, where each Class Data store constants and method code. So we have method code ONLY in one place. Thus, one line of method(which is later is bytecode in JVM) could be executed only by one thread at one core of CPU. Execution of same line of method cannot be performed at same time by two different threads on two different cores. But two DIFFERENT lines of code in method can be executed simultaneously by two different threads on two different cores. And each of thread can start execute method if no other thread executing first line of method.

So we have method code ONLY in one place.
Yes.
Thus, one line of method(which is later is bytecode in JVM) could be executed only by one thread at one core of CPU.
This is incorrect. Program memory is shared by all threads and this includes the classes and byte-code. Classes are locked when they are loaded but not when being executed or referenced without specific synchronization primitives being used.
Execution of same line of method cannot be performed at same time by two different threads on two different cores.
There is nothing that enforces this restriction.
And each of thread can start execute method if no other thread executing first line of method.
This is only true if a method is marked as synchronized and two threads are locking on the same object instance or if the method is static. See the following pseudo code.
public class Foo {
// many threads can be running bar() concurrently
public void bar() {
...
}
// threads that are using the same instance of Foo can only execute
// synchronized baz() and other synchronized methods one at a time.
// Threads using other instances can execute baz() concurrently
public synchronized void baz() {
...
}
// threads that are in the same classloader can only execute static
// synchronized bing() and other static synchronized methods one at a time
// because the class is being synchronized
public static synchronized void bing() {
...
}
}
This does not address memory sharing, message passing, or the other complex concepts involved with threaded programming.

Related

How to restrict access to a class to only one thread

I have a class called MathParser which has only one entry point which is "Evaluate" a static function which takes only one String input and outputs the evaluated result. The MathParser class has several booleans representing different functionality that can be switched on or off.
In a single threaded application, The evaluate function will throw exceptions if things are not in desired order, and once it gets hold of the control flow, it will release it only when the processing is done ensuring complete safety from any kind of unexpected behavior.
However, in a Multi-threaded Application, A different thread can also turn this switches on or off independently as they're all static and public variables, while the Evaluate function might still be processing the input. It can lead to all sorts of unexpected behaviors.
So I wanted to know if a class and it's members can be made to be accessible only by one thread, either Main or a background, this way, no other thread will mess up things while processing is still midway.
This is crying out for you to make this a class and the Evaluate() method non-static along with all the Booleans as non-static fields.
Then you can allocate an instance in a thread and no other thread will have access to it (unless you pass is between threads).
But your alternative is to make the static method synchronized synchronised static methods are exclusive to the class. Only one thread may be executing a synchronized static method on a give class at a time.
You would then make all the setters synchronized (static synchronized void setXxxx(boolean val)).
Having (of course) made all the flags private to the class.
Then no other thread can be setting the booleans while the Evaluate() method is executing.
But I can not stress enough that is not the way to go.
It's not the way to write multi-threaded code because it means that only one thread can be evaluating at any time for no good reason!
There is no logical reason why two threads can't be evaluating at the same time except for your decision that there shall be only one object that has an Evaluate method. That one object being the class MathParser.
The static method design may lead to entirely unnecessary resource contention.
It's like a class with only one calculator kept on the teachers desk and everyone has to line up to use it. But calculators are cheap and everyone could have their own.
Each thread can so easily have it's own parser.
The objective in concurrency it maximise parallelism and that means minimise waiting/blocking in which one or more threads cannot proceed until some other thread does something.
Use lock or synchronized :
https://www.baeldung.com/java-synchronized
You can learn more about that by researching "lock in multithreading".

How does the JVM guarantee the visibility of member variable modifications in the referenced object when using synchronized?

I want to know how does the JVM guarantee the visibility of member variable modifications in the referenced object when using synchronized.
I know synchronized and volatile will provide visibility for variable modifications.
class Test{
public int a=0;
public void modify(){
a+=1;
}
}
//Example:
// Thread A:
volatile Test test=new Test();
synchronized(locker){
test.modify();
}
// then thread B:
synchronized(locker){
test.modify();
}
// Now, I think test.a==2 is true. Is it ok? How JVM implements it?
// I know the memory barrier, does it flush all cache to main storage?
Thread A call modify in a sychronized block first, and then pass the object to thread B (Write the reference to a volatile variable.).
Then thread B call modify again (in synchronized).
Is there any guarantee for a==2? And how is the JVM implemented?
Visibility between threads is enforced with Memory Barriers/Fences. In case of synchronized block JVM will insert a memory barrier after the execution of the block completes.
JVM implements memory barriers with CPU instruction e.g. a store barrier is done with sfence and load barrier is done with lfence instruction on x86. There is also mfence and possibly other instructions which can be specific to CPU architecture.
For your (still incomplete!) example, if we can assume the following:
The code in thread A initializing test is guaranteed to run before thread B uses it.
The locker variable contains a reference to the same object for threads A & B.
then we can prove that a == 2 will be true at the point you indicate. If precondition 1 is not guaranteed, then thread B may get an NPE. If precondition 2 is not guaranteed (i.e. threads A and B may synchronize on different objects) then there is not a proper happens-before relationship to ensure that thread B sees the result of thread A's actions on a.
(#NathanHughes commented that the volatile is unnecessary. I wouldn't necessarily agree with that. It depends on details of your example that you still haven't show us.)
How JVM implements it?
The actual implementation is Java platform and (in theory) version specific. The JVM spec Memory Model places constraints on how a program that obeys "the rules" will behave. It is entirely implementation specific how that actually happens.
I know the memory barrier, does it flush all cache to main storage?
That is implementation specific too. There are different kinds of memory barrier that work in different ways. The JIT compiler will emit native code that uses the appropriate instructions to meet the guarantees required by the JLS. If there is a way to do this without doing a full cache flush then the implementation may do that.
(There is a JVM command line option to tell the JIT compiler to output the native code. If you really want to know what is happening under the hood, that is a good place to start looking.)
But if you are trying to understand / analyze your application's thread-safety, you should be doing it in terms of the Java Memory Model. Also, use higher level concurrency abstractions that allow you to avoid the lower level pitfalls.

Questions about how the synchronized keyword works with locks and thread starvation

In this java tutorial there's some code that shows an example to explain the use of the synchronized keyword. My point is, why I shouldn't write something like this:
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
//private Object lock1 = new Object();
//private Object lock2 = new Object();
public void inc1() {
synchronized(c1) {
c1++;
}
}
public void inc2() {
synchronized(c2) {
c2++;
}
}
}
Without bothering create lock objects? Also, why bother instantiate that lock objects? Can't I just pass a null reference? I think I'm missing out something here.
Also, assume that I've two public synchronized methods in the same class accessed by several thread. Is it true that the two methods will never be executed at the same time? If the answer is yes, is there a built-in mechanism that prevents one method from starvation (never been executed or been executed too few times compared to the other method)?
As #11thdimension has replied, you cannot synchronize on a primitive type (eg., long). It must be a class object.
So, you might be tempted to do something like the following:
Long c1 = 0;
public void incC1() {
synchronized(c1) {
c1++;
}
}
This will not work properly, as "c1++" is a shortcut for "c1 = c1 + 1", which actually assigns a new object to c1, and as such, two threads might end up in the same block of synchronized code.
For the lock to work properly, the object being synchronized upon should not be reassigned. (Well, maybe in some rare circumstances where you really know what you are doing.)
You cannot pass a null object to the synchronized(...) statement. Java is effectively creating semaphores on the ref'd object, and uses that information to prevent more than one thread accessing the same protected resource.
You do not always need a separate lock object, as in the case of a synchronized method. In this case, the class object instance itself is used to store the locking information, as if you used 'this' in the method iteslf:
public void incC1() {
synchronized(this) {
c1++;
}
}
First you can not pass primitive variable to synchronized, it requires a reference. Second that tutorial is just a example showing guarded block. It's not c1,c2 that it's trying to protect but it's trying to protect all the code inside synchronized block.
JVM uses Operating system's scheduling algorithm.
What is the JVM Scheduling algorithm?
So it's not JVM's responsibility to see if threads are starved. You can however assign priority of threads to prefer one over other to execute.
Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority. Each thread may or may not also be marked as a daemon. When code running in some thread creates a new Thread object, the new thread has its priority initially set equal to the priority of the creating thread, and is a daemon thread if and only if the creating thread is a daemon.
From:https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html
If you're concerned about this scenario then you have to implement it yourself. Like maintaining a thread which checks for starving threads and as time passes it increases the priority of the threads which have been waiting longer than others.
Yes it's true that two method which have been synchronized will never be executed on the same instance simultaneously.
Why bother instantiate that lock objects? Can't I just pass a null reference?
As others have mentioned, you cannot lock on long c1 because it is a primitive. Java locks on the monitor associated with an object instance. This is why you also can't lock on null.
The thread tutorial is trying to demonstrate a good pattern which is to create private final lock objects to precisely control the mutex locations that you are trying to protect. Calling synchronized on this or other public objects can cause external callers to block your methods which may not be what you want.
The tutorial explains this:
All updates of these fields must be synchronized, but there's no reason to prevent an update of c1 from being interleaved with an update of c2 — and doing so reduces concurrency by creating unnecessary blocking. Instead of using synchronized methods or otherwise using the lock associated with this, we create two objects solely to provide locks.
So they are also trying to allow updates to c1 and updates to c2 to happen concurrently ("interleaved") and not block each other while at the same time making sure that the updates are protected.
Assume that I've two public synchronized methods in the same class accessed by several thread. Is it true that the two methods will never be executed at the same time?
If one thread is working in a synchronized method of an object, another thread will be blocked if it tries the same or another synchronized method of the same object. Threads can run methods on different objects concurrently.
If the answer is yes, is there a built-in mechanism that prevents one method from starvation (never been executed or been executed too few times compared to the other method)?
As mentioned, this is handled by the native thread constructs from the operating system. All modern OS' handle thread starvation which is especially important if the threads have different priorities.

Partially constructed objects in non thread-safe Singleton

In a multi-threaded environment, how can a thread possibly see a 'partially constructed object'? I understood that it is not thread-safe since multiple threads can create multiple instances.
class LazyInit
{ private static Resource resource = null;
public static getInstance()
{ if (resource == null) { resource = new Resource(); }
return instance;
}
}
Because of out-of-order writes.
If your constructor writes to non-final members, they don't have to be committed to memory right away, and actually they may even be committed after the singleton variable is. Java guarantees the thread that affects it sees the affectations in order, but not that other threads will unless you put a memory barrier.
See this question and this page of the Java specification for more information.
It might be beside the point but in your example, it is entirely possible that two threads see different singletons. Suppose one thread tests the nullity of the variable, enters the if and gets preempted before it gets a chance to construct the object. The new thread that gets the CPU now tests the yet-null object, constructs the singleton. When the old thread starts running again it will happily finish constructing the object and overwrite the singleton variable.
Another, more frightening issue, arises if the constructor of Resource calls for a method that will ultimately result in another call to this getInstance. Even if the state of the program results in no infinite loop, you will create several singleton instances.

is this class thread safe?

consider this class,with no instance variables and only methods which are non-synchronous can we infer from this info that this class in Thread-safe?
public class test{
public void test1{
// do something
}
public void test2{
// do something
}
public void test3{
// do something
}
}
It depends entirely on what state the methods mutate. If they mutate no shared state, they're thread safe. If they mutate only local state, they're thread-safe. If they only call methods that are thread-safe, they're thread-safe.
Not being thread safe means that if multiple threads try to access the object at the same time, something might change from one access to the next, and cause issues. Consider the following:
int incrementCount() {
this.count++;
// ... Do some other stuff
return this.count;
}
would not be thread safe. Why is it not? Imagine thread 1 accesses it, count is increased, then some processing occurs. While going through the function, another thread accesses it, increasing count again. The first thread, which had it go from, say, 1 to 2, would now have it go from 1 to 3 when it returns. Thread 2 would see it go from 1 to 3 as well, so what happened to 2?
In this case, you would want something like this (keeping in mind that this isn't any language-specific code, but closest to Java, one of only 2 I've done threading in)
int incrementCount() synchronized {
this.count++;
// ... Do some other stuff
return this.count;
}
The synchronized keyword here would make sure that as long as one thread is accessing it, no other threads could. This would mean that thread 1 hits it, count goes from 1 to 2, as expected. Thread 2 hits it while 1 is processing, it has to wait until thread 1 is done. When it's done, thread 1 gets a return of 2, then thread 2 goes throguh, and gets the expected 3.
Now, an example, similar to what you have there, that would be entirely thread-safe, no matter what:
int incrementCount(int count) {
count++;
// ... Do some other stuff
return this.count;
}
As the only variables being touched here are fully local to the function, there is no case where two threads accessing it at the same time could try working with data changed from the other. This would make it thread safe.
So, to answer the question, assuming that the functions don't modify anything outside of the specific called function, then yes, the class could be deemed to be thread-safe.
Consider the following quote from an article about thread safety ("Java theory and practice: Characterizing thread safety"):
In reality, any definition of thread safety is going to have a certain degree of circularity, as it must appeal to the class's specification -- which is an informal, prose description of what the class does, its side effects, which states are valid or invalid, invariants, preconditions, postconditions, and so on. (Constraints on an object's state imposed by the specification apply only to the externally visible state -- that which can be observed by calling its public methods and accessing its public fields -- rather than its internal state, which is what is actually represented in its private fields.)
Thread safety
For a class to be thread-safe, it first must behave correctly in a single-threaded environment. If a class is correctly implemented, which is another way of saying that it conforms to its specification, no sequence of operations (reads or writes of public fields and calls to public methods) on objects of that class should be able to put the object into an invalid state, observe the object to be in an invalid state, or violate any of the class's invariants, preconditions, or postconditions.
Furthermore, for a class to be thread-safe, it must continue to behave correctly, in the sense described above, when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, without any additional synchronization on the part of the calling code. The effect is that operations on a thread-safe object will appear to all threads to occur in a fixed, globally consistent order.
So your class itself is thread-safe, as long as it doesn't have any side effects. As soon as the methods mutate any external objects (e.g. some singletons, as already mentioned by others) it's not any longer thread-safe.
Depends on what happens inside those methods. If they manipulate / call any method parameters or global variables / singletons which are not themselves thread safe, the class is not thread safe either.
(yes I see that the methods as shown here here have no parameters, but no brackets either, so this is obviously not full working code - it wouldn't even compile as is.)
yes, as long as there are no instance variables. method calls using only input parameters and local variables are inherently thread-safe. you might consider making the methods static too, to reflect this.
If it has no mutable state - it's thread safe. If you have no state - you're thread safe by association.
No, I don't think so.
For example, one of the methods could obtain a (non-thread-safe) singleton object from another class and mutate that object.
Yes - this class is thread safe but this does not mean that your application is.
An application is thread safe if the threads in it cannot concurrently access heap state. All objects in Java (and therefore all of their fields) are created on the heap. So, if there are no fields in an object then it is thread safe.
In any practical application, objects will have state. If you can guarantee that these objects are not accessed concurrently then you have a thread safe application.
There are ways of optimizing access to shared state e.g. Atomic variables or with carful use of the volatile keyword, but I think this is going beyond what you've asked.
I hope this helps.

Categories