How JVM is able to process simultaneously spring singleton code? - java

I would like to ask you about how internally Spring Singleton will work in concurrency software. Please use as many details as you know. I want to know deply how JVM is resolve that.
I find similar question here - however that one concer two separate methods invoked by two separate thread - here I have one method and two threads
#Component
public class SpringSingleton {
public void justWait(){
try {
Thread.sleep(5000);
}
catch(InterruptedException ex) {}
}
}
#Component
public class StartClass {
#Autowired
private SpringSingleton singleton;
public void runAfterAppStart(){
for(int i=0; i<=1; i++){
CompletableFuture.runAsync(() -> singleton.justWait());
}
}
}
After running these piece of code, you'll see that two threads are end at almost same time.
How it is possible? Why Thread2 doesn't have to wait until Thread1 will finish his work?
As I understand whole flow, instance of SpringSingleton class will be placed on JVM Heap, then on stack Java will place two threads (Thread1,Thread2). Each of thread will contains own (independant) reference to Spring Singleton class - now...
Thread1 will use his reference to execute method "justWait". These method is obviously some instructions for processor. So if these instructions are currently processes - how Thread2 is able to invoke them?
The only explanation for me is, JVM will somehow copy byte code from heap to each thread - then everythink is clear - but it is really happening here?
Thank you for explanation of that problem. Even buzzwords which I can google will be really helpful

How it is possible? Why Thread2 doesn't have to wait until Thread1 will finish his work?
Because you don't have any synchronisation going on.
The only explanation for me is, JVM will somehow copy byte code from heap to each thread - then everythink is clear - but it is really happening here?
You're mixing up two things: instance variables and bytecode. Bytecode is the compiled Java code, and is present only once, and not on the heap. Instance variables are created on the heap, but each thread will have its own set.
In this example, however, there aren't any instance variables. So each thread simply runs the same bytecode. There is no need to wait, because bytecode doesn't change after it's been loaded.

Your question is not related to Spring Singleton implementation.
There are 3 threads. One main thread and 2 CompletableFuture threads. Main thread creates completable futures, finish it's work and application exits. It doesn't wait for the CompletableFuture to complete.
You can check this by adding additional Thread.sleep(10000) after the loop, for example:
public void runAfterAppStart(){
for(int i=0; i<=1; i++){
CompletableFuture.runAsync(() -> singleton.justWait());
}
// Hold main thread for the CompletableFuture to complete.
Thread.sleep(10000);
}

Why Thread2 doesn't have to wait until Thread1 will finish his work?
Because threads are specifically made to do not wait one another.
If you want one thread to wait until another completes use synchronized method or block.
Singleton methods are re-entrant, because actual code is in the class object.
Even if there are two non-singleton objects, still there is only one instance of code in the class.
When object(bean) is a singleton it means there is only one instance of that class and assigned memory for its data - instance variables.
The only explanation for me is, JVM will somehow copy byte code from heap to each thread
it is wrong
BTW: in real there is no such thing as "simultaneously" it is just a matter of nanoseconds between thread switching...

I can help with your last couple paragraphs--
There is just 1 copy of the code but both threads are able to run through it at the same time. It's possible that both cores of a cpu are running through the code at EXACTLY the same time, but each CPU points to different data so that the exact same code might operate on different data.
In fact, one CPU may have data that evaluates to "true" another might evaluate to "false" so that an if() statement causes the threads to diverge.
The problem is there aren't enough CPUs so we have a way to save and restore the state of a single CPU so that it can act like multiple CPUs to a certain extent--each of these virtual CPUs is a thread.
Since they can save their state, a single CPU can run thousands of threads at (seemingly) the same time by stopping and restarting them thousands of times a second.
The short of it is that it's just one copy of the code but different data for each thread.

Related

Why is this working? (generating values in main thread and consuming them in some other background thread in Android)

As far as I know, threads copy variables in their local cache.
What I'm doing is, I'm getting values in the main thread and then I'm consuming them in some other background (renderer) thread. Like this-
class MySurfaceView ... {
private var someValue = 0
// Called from the main thread
fun updateValue() {
someValue++
}
fun render() {
Thread {
// Here someValue variable is consumed
// and it's always up to date.
....
}.start()
}
}
So, inside the runnable passed to the thread started inside render(), 'someValue' is always up to date and I didn't even mark it volatile. If threads copy variables to their local cache then why is it happening? Is it because an implicit reference of the outer class is being kept and the value is coming from there (if this is true, then in cases like this, where I have one generator and multiple consumer threads, would it always be safe to not mark the field which is updated only by the generator thread as volatile? As read/write operations on volatile is costly)?
The same thing also happens when I start a coroutine and try access 'someValue' inside it.
threads copy variables in their local cache.
This is not true, which explains your findings. Basically, you confused the liberties an implementation may exercise with guarantees the specification provides. The Java Memory Model (which Kotlin follows as well) simply gives the implementation the freedom to do whatever it likes with state that doesn't get shared through synchronizing actions. It may store it on the stack or in a register, and it may also work with the original on the heap.
One especially relevant detail is that println() is a synchronized method, so if in your actual code you had printlns in both threads to see what's going on, you introduced synchronization that made the results come out right.
On the other hand, it's quite easy to see a program that takes this freedom, for example
Thread 1:
var runningFlag = true
while (runningFlag) {}
Thread 2:
sleep(1000)
runningFlag = false
Thread 1 is quite likely to go on executing forever, or even to be compiled similar to currentThread().join() -- doing no actual work, but never completing.

Best practice when waiting for multiple threads - time, count or something else?

My application will, during runtime, contain multiple threads (in this example 7) doing independent work. However, every once in a while, the threads will have to synchronize their data.
This will be done by the threads calling the DataSynchronizer object which they all have a reference to.
My idea for flow in this class looks like this:
public class DataSynchronizer {
public void synchronizeData(List<Data> threadData) {
// Wait for all 7 threads to call this method
// When all 7 are here, hold them here & do work using one of the threads
// or a new anonymous thread
// Release the threads & let them continue their independent work
}
}
My question is, what is the best way for me to 'wait for all x threads' before doing the synch work?
I know that all threads will call the synchronizeData method within 1, max 2 seconds of each other.
So do I,
1) Wait for 2s after the first thread call the method and assume all threads have now also arrived? or
2) Keep a count to make sure all active threads have arrived? (App will wait for eternity if a thread crashes just before calling method)
3) Count + timeout?
4) ???
This is what a CyclicBarrier is for. It allows you to define spots where threads will wait until all arrive, and then optionally run a Runnable to perform synchronization or other such thing.
I think you need a java.util.concurrent.CyclicBarrier.
Assume and threads is a very risky approach.
How bad is waiting for an eternity? Sounds inconvenient to me.
If you hit the timeout can you do something useful? Crash the program, restart the errant thread, assume something about what it is doing?
Follow-on questions:
What happens if a thread doesn't participate in the synchronisation?
What happens if the sync is late?
Should your method tell one thread from another, or are they just 7 interchangeable workers?

Static method behavior in multi-threaded environment in java

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?
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.
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).

Implementing a Mutex in Java

I have a multi-threaded application (a web app in Tomcat to be exact). In it there is a class that almost every thread will have its own instance of. In that class there is a section of code in one method that only ONE thread (user) can execute at a time. My research has led me to believe that what I need here is a mutex (which is a semaphore with a count of 1, it would seem).
So, after a bit more research, I think what I should do is the following. Of importance is to note that my lock Object is static.
Am I doing it correctly?
public Class MyClass {
private static Object lock = new Object();
public void myMethod() {
// Stuff that multiple threads can execute simultaneously.
synchronized(MyClass.lock) {
// Stuff that only one thread may execute at a time.
}
}
}
In your code, myMethod may be executed in any thread, but only in one at a time. That means that there can never be two threads executing this method at the same time. I think that's what you want - so: Yes.
Typically, the multithreading problem comes from mutability - where two or more threads are accessing the same data structure and one or more of them modifies it.
The first instinct is to control the access order using locking, as you've suggested - however you can quickly run into lock contention where your application looses a lot of processing time to context switching as your threads are parked on lock monitors.
You can get rid of most of the problem by moving to immutable data structures - so you return a new object from the setters, rather than modifying the existing one, as well as utilising concurrent collections, such a ConcurrentHashMap / CopyOnWriteArrayList.
Concurrent programming is something you'll need to get your head around, especially as throughput comes from parallelisation in todays modern computing world.
This will allow one thread at a time through the block. Other thread will wait, but no queue as such, there is no guarantee that threads will get the lock in a fair manner. In fact with Biased lock, its unlikely to be fair. ;)
Your lock should be final If there is any reason it can't its probably a bug. BTW: You might be able to use synchronized(MyClass.class) instead.

Remove blocking from a method

This is homework.
I do not want the solution, just a small number of links or ideas.
Simply speaking what I want to do is,
Simple example :
public class Example
{
public void method()
{
int x = doThat();
//Call other methods which do not depend on x
return;
}
}
doThat() is a method that is known to be time consuming, which results in my program blocking until results are back. And I want to use different methods of this Object, but program is frozen until doThat() is finished. Those different methods do not necesserely have to be invoked from the method() used in this example, but maybe from outside the object.
I thought about using threads but if I have a huge number of objects (1000+) this probably wont be very efficient (correct me if I am wrong please). I guess if I use threads I have to use one thread per object ?
Is there any other way besides threads that can make the invoking object not block when calling doThat(); ? If threading is the only way, could you provide a link ?
Knowing questions like that get downvoted I will accept any downvotes. But please just a link would be more than great.
Thanks in advance. I hope question is inline with the rules.
I'd also use threads for this, but I simply wanted to add that it would probably be interesting to look at java.util.concurrent.Executors (to create thread pools as you have a number of objects) and the java.util.concurrent.Future and java.util.concurrent.Callable classes which will allow you to launch threads that can return a value.
Take a look at the concurrency tutorial for more info.
I recommend you to create a class that implements Runnable, whose run method does what doThat() does in your sample. Then you can invoke it in a separate Thread in a simple way. Java's Thread class does have a constructor that takes a runnable. Use the run and join methods.
Cheers
Matthias
Of course threads are the only solution to handle some jobs in backgrounds, but
you are not forced to use a thread just for a single operation to be performed.
You can use only one thread that maintains a queue of operations to be performed, in a way that every call to the method doThat adds a new entry into the queue.
Maybe some design patterns like "Strategy" can help you to generalize the concept of operation to be performed, in order to store "operation objects" into the thread's queue.
You want to perform several things concurrently, so using threads is indeed the way to go. The Java tutorial concurrency lesson will probably help you.
1000 concurrent threads will impose a heavy memory load, because a certain amount of stack memory is allocated for each thread (2 MB?). If, however, you can somehow make sure there will be only one Thread running at a time, you still can take the thread per object approach. This would require you to manage that doThat() is only called, if the thread produced by a former invocation on another object has already finished.
If you cannot ensure that easily, the other approach would be to construct one worker thread which reads from a double ended queue which object to work on. The doThat() method would then just add this to the end of the queue, from which the worker thread will later extract it. You have to properly synchronize when accessing any data structure from concurrent threads. And the main thread should somehow notify the worker thread of the condition, that it will not add any more objects to the queue, so the worker thread can cleanly terminate.

Categories

Resources