I'm new to concurrent programming in Java. I've noticed that the methods sleep() and currentThread() of the Thread class are static. Since with a multi-core CPU, many threads can run at the same time, I was wondering how the thread is chosen between the ones in execution. Thank you.
That's easily found in the Javadocs for Thread:
For currentThread():
Returns a reference to the currently executing thread object.
For sleep():
Causes the currently executing thread to sleep
I.e. the Thread that calls the method for both methods.
Related
In Java, a thread can go to sleep so that it won't hog the process and other thread can get chance to run. This is done by calling sleep().
However, different from calling wait(), the thread, after calling sleep(), will NOT release the lock it's been holding. Since this thread is still holding the lock, how can other thread get chance to run while not being able to get the unreleased lock?
They can't; other threads that need to acquire a lock held by a sleeping thread will block until they can get it. There's no way to back off like tryacquire on explicit Locks, so the threads are stuck.
Threads shouldn't sleep while holding a lock. If a thread isn't doing something useful it doesn't need to be holding a lock.
To go dormant and release a lock use the wait method. Sleep doesn't have any means to cut its sleep time short other than interruption (which should be used for cancellation), wait lets the thread be notified.
If you call Thread.sleep() while holding a lock or from inside a synchronized block/method, any other threads that reach that lock will wait until the first thread resumes and releases the lock.
However locks/synchronization are not global, any threads that don't reach the locks held by the sleeping thread can run without issue.
If other thread can't get the lock to run while this thread is going to sleep, then what's the purpose for this thread to go sleep at first place?
The only person who can answer that question is the person who wrote the code that runs in the thread.
Was that you?
As Nathan Hughes said, it practically never is a good idea for a thread to sleep() while holding a mutex lock. To take that idea a little further: It almost never is a good idea for a thread to do anything that takes more than a microsecond or so while holding a mutex lock. If you find yourself writing code that waits for something while keeping a lock locked, then that's a sign that you might need to re-think the architecture.
Also, there are not many good reasons for calling sleep() at all.
In Java, a thread can go to sleep so that it won't hog the process and other thread can get chance to run.
That's not really what sleep() is for. In most cases, when a thread doesn't need the CPU, it will block in a wait() call or in some xyz.await() call (where xyz is a queue or a semaphore or a latch or some other higher-level synchronization object).
The sleep() function is a low-level, primitive that your program can call in order to meet real-time requirements. But most programs with real-time requirements can make use of higher-level facilities such as java.util.concurrent.ScheduledThreadPoolExecutor
or javax.swing.Timer. If you start by writing your own sleep() calls, without first investigating the higher-level objects, then you may be re-inventing a wheel.
sleep() is a static method of class Thread. How does it work when called from multiple threads. and how does it figure out the current thread of execution. ?
or may be a more generic Question would be How are static methods called from different threads ? Won't there be any concurrency problems ?
how does it figure out the current
thread of execution?
It doesn't have to. It just calls the operating system, which always sleeps the thread that called it.
The sleep method sleeps the current thread so if you are calling it from multiple threads it will sleep each of those threads. Also there's the currentThread static method which allows you to get the current executing thread.
a more generic Question would be How are static methods called from different threads ? Won't there be any concurrency problems ?
There is only a potential concurrency problem if one or more thread modifies shared state while another thread uses the same state. There is no shared state for the sleep() method.
Thread.sleep(long) is implemented natively in the java.lang.Thread class. Here's a part of its API doc:
Causes the currently executing thread to sleep (temporarily cease
execution) for the specified number of milliseconds, subject to
the precision and accuracy of system timers and schedulers. The thread
does not lose ownership of any monitors.
The sleep method sleeps the thread that called it.(Based on EJP's comments) determines the currently executing thread (which called it and cause it to sleep). Java methods can determine which thread is executing it by calling Thread.currentThread()
Methods (static or non static) can be called from any number of threads simultaneously. Threre will not be any concurrency problems as long as your methods are thread safe.
You will have problems only when multiple Threads are modifying internal state of class or instance without proper synchronization.
When the virtual machine encounters a sleep(long)-statement, it will interrupt the Thread currently running. "The current Thread" on that moment is always the thread that called Thread.sleep(). Then it says:
Hey! Nothing to do in this thread (Because I have to wait). I'm going to continue an other Thread.
Changing thread is called "to yield". (Note: you can yield by yourself by calling Thread.yield();)
So, it doesn't have to figure out what the current Thread is. It is always the Thread that called sleep().
Note: You can get the current thread by calling Thread.currentThread();
A short example:
// here it is 0 millis
blahblah(); // do some stuff
// here it is 2 millis
new Thread(new MyRunnable()).start(); // We start an other thread
// here it is 2 millis
Thread.sleep(1000);
// here it is 1002 millis
MyRunnable its run() method:
// here it is 2 millis; because we got started at 2 millis
blahblah2(); // Do some other stuff
// here it is 25 millis;
Thread.sleep(300); // after calling this line the two threads are sleeping...
// here it is 325 millis;
... // some stuff
// here it is 328 millis;
return; // we are done;
Thread.currentThread() can use to get the currently executing thread. And as I think both of the sleep and yield methods are static because they can't execute sleep or yield on other threads. So by making them static it will sleep or yield only the currently executing thread.
This seems to be working in single processor system, if I callThread.currentThread() or sleep then there's only the currently running thread, it will return or it will sleep. But in a multicore system, multiple threads can run at once,
So how Thread.currentThread() or Thread.sleep() works...?
The method Thread.currentThread() returns the thread which we are currently running inside. It is simply a way of saying: "Hey give me a reference of the thread that is running me"
Suppose we have four cores and four threads A,B,C and D are running absolutely concurrently, calling this method at the same time, it will return A, B, C and D appropriately based upon the thread we are currently in.
And methods Thread.currentThread().sleep() or Thread.sleep() are doing essentially the same job. As per the documentation for currentThread():
public static Thread currentThread()
Returns a reference to the currently executing thread object.
and
public static void sleep(long millis)throws InterruptedException
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.
The documentation is very poor in this case. What Thread.currentThread() returns is actually the thread where you execute that line of code in. So whether you are in a multi-processor environment or not doesn't matter in this case.
When you have two threads ThreadA and ThreadB running completely in parallel and you ask for Thread.currentThread() in parallel at the same time you will get the corresponding thread where this is executed.
These methods are static because you can access to the current execution thread of your core/CPU that is executing that code.
If there is more than one core or CPU processors, each core that passes through this code will return to you its own thread.
So you don't need to care about how many cores/CPUs are in the system, these methods will work in both scenarios a single core and multicore systems.
Remember that Java Thread is an abstraction of the OS real Thread (posix, windows...) so you can code your program without caring about OS architectures.
it works only for the "current" thread. In a multicore system if your code is single threaded only one thread is running and this is the current one so this code will work on that one. If you have multithreading program this code will work in the thread it is called. The number of cores doesn't really matter. Java distributes the threads and the load to the different cores but from code's point of view number of processors doesn't matter.
I have a few questions about Java multi-threading. I am currently learning different methods of multi-threading. My first question is, what happens to the thread after the code in it is done running? Do I need to Stop/Kill the thread? I am currently making a class for each thread and implementing Runnable in each class. I then start the thread in the main class using new ThreadClass();. In the constructor of the Thread class, I have it set to make a Thread named "second." If I add new ThreadClass() twice in the main method, are both threads named "second"? Thanks.
My first question is, what happens to the thread after the code in it is done running? Do I need to Stop/Kill the thread?
The thread stops when it has nothing to do. If you have an ExecutorService, you have to use shutdown when you have finished with it.
If I add new ThreadClass() twice in the main method, are both threads named "second"?
You are making the code the same. This doesn't mean the name of the thread has to be the same (and vice-versa)
I assume you mean Thread rather than ThreadClass.
When the run method of a thread returns then the thread will stop. If you only specify the name in the second thread then only that thread will have the name "second". The first thread is unaffected.
You should avoid calling stop if at all possible as it does not allow the thread to exit cleanly.
Doing some studying about threads and I'm confused about what the start() method in Java threads actually do.
My current understanding is that the start method doesn't immediately start the thread's execution, but instead moves it to a pool of threads waiting for it be picked for execution by the thread scheduler.
Is this correct? I can't seem to find any good resources about what the methods actually do.
Exactly, when a call to start() is performed, it just schedules the call to run(). You cannot determinate when the thread will effectively be launched, nor when it will effectively be stopped.
You can find more information in the Java Doc on oracle's website.
start
public void start() Causes this thread to begin execution; the Java
Virtual Machine calls the run method of this thread. The result is
that two threads are running concurrently: the current thread (which
returns from the call to the start method) and the other thread (which
executes its run method).
Throws: IllegalThreadStateException - if the thread was already
started. See Also: run(), stop()
Source
You are confusing Threads with ThreadPools
A thread is an "unit of execution", code executed on a separate thread runs in parallel with your main programs when you call start()
ThreadPools is a mechanism built on top of threads, it allows you to create a group of threads which will take care to execute tasks you submit to the ThreadPool queue.
Yes, this is correct. You don't know when this thread will be executed but for sure it is scheduled for running.
Have a look at the following picture. It explains the lifecycle of a thread: http://cs.fit.edu/~ryan/java/language/thread.gif
start immediately starts the new thread, but by the very nature of threads, there is no guarantee as to when any line of code in that thread will actually execute. It is not appropriate to use the term "thread pool" in this context because the concept of a pool involves resources that are reused between user-requested tasks. A Thread instance is hardwired to a single invocation of the run method, after which the thread dies.
The thread scheduler is a native OS-level component and is not under the direct control of the JVM.
When you call Thread.start it makes a special instarcution to JVM for starting a thread and JVM will taken care of its life cycle.