When I was going through Javadoc for CountDownLatch, I came across a line in the documentation for await method.
If the current count is greater than zero then the current thread
becomes disabled for thread scheduling purposes and lies dormant
What is meant by current thread becomes disabled for thread scheduling purposes here?
On a given system, only a fixed number of threads can actually execute at the same time (you're limited by the number of cores in the machine.) When there are more threads to run than there are cores, the thread scheduler will cycle through the threads in some fashion, giving each a bit of time on the CPU.
However, in some cases it doesn't make sense to give a thread time on the CPU. For example, if a thread acquires a countdown latch whose total is greater than zero, then that thread is stuck waiting for other threads to also acquire the latch. It therefore doesn't make any sense to let that thread have any CPU time, since the thread is just sitting and waiting for other threads. Therefore, typically, the scheduler would not even attempt to give the thread any CPU time, preferring instead to schedule other threads that can still make progress. Once enough threads do acquire the countdown latch, all threads that were blocked this way are then put back into the scheduler for further consideration.
In other words, the thread stops running and the scheduler will intelligently not waste time trying to run it until the latch is ready.
Hope this helps!
It just means that the code in that thread will not go any further until latch.countDown() is called on the same latch from other threads thereby making the latch count 0.
A thread runs when it is in runnable state and the scheduler schedules it. When a threads is disabled for scheduling, it will not get its share of cpu cycles, so it wont run which means its program counter will not increase. Its stack will freeze where it was till it gets the cpu again.
Related
I have a thread pool created from ThreadPoolTaskExecutor:
threadPoolTaskExecutor.setCorePoolSize(10);
this ThreadPoolTaskExecutor will execute runnables, each runnable has a Thread.sleep(6000); call during the task execution.
So when I execute the 1st task and when the 1st task calls Thread.sleep(6000) to sleep, at that time, execute the 2nd task, will it be possible the 2nd task will use the thread of the 1st task or interrupt the thread used by the 1st task? since it is in sleep.
No, not automatically. If a normal Java Thread is sleeping, then it's sleeping.
Also, Threads are really cheap nowadays, I would not bother with details like that.
Working around the sleep and let that 'sleeping' Thread do some other work is really really hard to manage properly and easily will lead to loads and loads of unforeseen problems.
In your situation, what you COULD improve is that the pool size is not fixed but dynamic, releasing (destroying) threads when they haven't been used for some time (say: a minute).
If more threads are needed, the pool will create new Threads, up to the given limit. (Executors.newCachedThreadPool())
That's especially helpful on a server, because 99% of threads on there are just idle (not even 'actively' sleeping).
Here are some details that might interest you: https://www.baeldung.com/thread-pool-java-and-guava
Especially check out ForkJoinPool: https://www.baeldung.com/java-fork-join, because this comes very close to a very similar problem.
I was reading about yield. It is being told that if a thread is running long and if another thread who is going to run for short time need to wait for long running thread to finish its processing. But my question is as per thread scheduler, no thread will run till its completion in one go. it has to oscillate between running and ready states. so will be the case with long running thread. eventually it will move from running to ready after some time and then will resume its works and this cycle will go on till it completes its job. then what is the role of yield? Is it just a voluntary way of moving to ready state to see if anyone need process time ?
Below is the information from https://www.geeksforgeeks.org/java-concurrency-yield-sleep-and-join-methods/ which could not clear my doubt.
yield(): Suppose there are three threads t1, t2, and t3. Thread t1 gets the processor and starts its execution and thread t2 and t3 are in Ready/Runnable state. Completion time for thread t1 is 5 hour and completion time for t2 is 5 minutes. Since t1 will complete its execution after 5 hours, t2 has to wait for 5 hours to just finish 5 minutes job. In such scenarios where one thread is taking too much time to complete its execution, we need a way to prevent execution of a thread in between if something important is pending. yeild() helps us in doing so.
yield() basically means that the thread is not doing anything particularly important and if any other threads or processes need to be run, they should run. Otherwise, the current thread will continue to run.
yield() says to the Java runtime "You may now proceed with another thread". With current operating systems (like Unix or Windwos) which have native threads and preemptive multitasking, a long running thread will be eventually paused for some time and other threads will be executing. With yield() this will possibly happen earlier.
On current environments this functionality is not important in most cases. It is especially useful, if you have only cooperaive multitasking, when there is effectively only one thread and another process can only execute when the current process explictly allows to be paused by calling yield().
Could you explain me, why in ScheduledThreadPoolExecutor javadoc is this:
Additionally, it is almost never a good idea to set corePoolSize to
zero or use allowCoreThreadTimeOut because this may leave the pool without
threads to handle tasks once they become eligible to run.
I've tried to analyze how new threads are created in this thread pool when a new task has to be executed and I think problem described in javadoc shouldn't happen.
The thread pool trys to make the number of work threads equals corePoolSize, to improve efficiency by caching threads. Allowing core thread time out is contrary to this purpose. If you allow core thread time out, new task will be executed, but leads to repeatly create and destroy work threads.
If you set allowCoreThreadTimeOut = true, then after the work thread find no task in task queue and time out, they will be destroyed even the number of working threads is less than corePoolSize. So, if you submit new task at this time, the thread pool has to create new thread.
If you set allowCoreThreadTimeOut = false, then after the work thread find no task in task queue and number of work threads less than corePoolSize, they will be not be destroyed and keep waiting for new task.
My guess is that the answer is stale Javadoc, for the most part. As you note, ensurePrestart ensures that as long as corePoolSize > 0, the number of core pool threads is nonzero after the call. This has been the case since https://github.com/openjdk/jdk/commit/2d19ea519b17529a083a62eb219da532693bbef3, but notably that commit did not update the Javadoc on ScheduledThreadPoolExecutor.
However, the details aren't quite so simple either. Rather than only worrying about new task submissions and task reschedule on completion, you also need to worry about core pool threads idling out because all scheduled tasks are too far in the future to trigger before the pool timeout.
Not sure if I'm reading the JRE code correctly, but it looks like in such a case, the pool will:
Start a worker thread (due to ensurePrestart)
Regardless of thread type (core or not), the thread is eligible for timeout because allowCoreThreadTimeout is true
Worker thread polls DelayedWorkQueue for next task, with timeout
poll returns null (times out), because the next scheduled task is beyond pool timeout
The core thread will terminate because it thinks there is nothing to do
ThreadPoolExecutor.processWorkerExit will run on worker termination. It will check the queue, notice that it's nonempty, and thus require a minimum of at least one thread
If the thread being terminated is the last thread, it will notice that the minimum is not met and immediately start a new (non-core) worker
Repeat from step 1
So, the pool will work as you intend, but probably won't be in an ideal state either (you really want a single core thread polling without timeout here, not threads constantly spinning up, polling with timeout, timing out, then starting a new thread to replace itself). In that sense, step 6 is really what prevents the case mentioned in Javadoc (by the time tasks are eligible, all pool threads have timed out), but it does so imperfectly because of the unnecessary thread creation/destruction loop.
This weirdness is really because DelayedWorkQueue semantically breaks the BlockingQueue contract. All else equal, you'd assume that size() > 0 implies that a subsequent poll(...) will successfully retrieve an element and not time out, but DelayedWorkQueue allows those elements to be held back for some time (even though they're already visible via size() and isEmpty()).
NOTE: Seems like this code changed in Java 8, with the addition of this condition to ThreadPoolExecutor.getTask(). This will keep that last worker thread alive and avoid the thread create/destroy loop, but it will busy-poll the work queue for work instead.
As currently executing thread while it encounters the call sleep() then thread moves immediately into sleeping stat.
Whereas for yield() thread moves into runnable state / ready state.
We can prevent a thread from execution by using any of the 3 methods of Thread class:
yield() method pauses the currently executing thread temporarily for giving a chance to the remaining waiting threads of the same priority or higher priority to execute. If there is no waiting thread or all the waiting threads have a lower priority then the same thread will continue its execution. The yielded thread when it will get the chance for execution is decided by the thread scheduler whose behavior is vendor dependent.
join() If any executing thread t1 calls join() on t2 (i.e. t2.join()) immediately t1 will enter into waiting state until t2 completes its execution.
sleep() Based on our requirement we can make a thread to be in sleeping state for a specified period of time (hope not much explanation required for our favorite method).
sleep() causes the thread to definitely stop executing for a given amount of time; if no other thread or process needs to be run, the CPU will be idle (and probably enter a power saving mode).
yield() basically means that the thread is not doing anything particularly important and if any other threads or processes need to be run, they should. Otherwise, the current thread will continue to run.
Sleep() causes the currently executing thread to sleep (temporarily cease execution).
Yield() causes the currently executing thread object to temporarily pause and allow other threads to execute.
Read [this] (Link Removed) for a good explanation of the topic.
Sleep causes thread to suspend itself for x milliseconds while yield suspends the thread and immediately moves it to the ready queue (the queue which the CPU uses to run threads).
Yield : will make thread to wait for the currently executing thread and the thread which has called yield() will attaches itself at the end of the thread execution. The thread which call yield() will be in Blocked state till its turn.
Sleep : will cause the thread to sleep in sleep mode for span of time mentioned in arguments.
Join : t1 and t2 are two threads , t2.join() is called then t1 enters into wait state until t2 completes execution. Then t1 will into runnable state then our specialist JVM thread scheduler will pick t1 based on criteria's.
Yield(): method will stop the currently executing thread and give a chance to another thread of same priority which are waiting in queue. If thier is no thread then current thread will continue to execute. CPU will never be in ideal state.
Sleep(): method will stop the thread for particular time (time will be given in milisecond). If this is single thread which is running then CPU will be in ideal state at that period of time.
Both are static menthod.
Yield: It is a hint (not guaranteed) to the scheduler that you have done enough and that some other thread of same priority might run and use the CPU.
Thread.sleep();
Sleep: It blocks the execution of that particular thread for a given time.
TimeUnit.MILLISECONDS.sleep(1000);
yield(): yield method is used to pause the execution of currently running process so that other waiting thread with the same priority will get CPU to execute.Threads with lower priority will not be executed on yield. if there is no waiting thread then this thread will start its execution.
join(): join method stops currently executing thread and wait for another to complete on which in calls the join method after that it will resume its own execution.
For detailed explanation, see this link.
One way to request the current thread to relinquish CPU so that other threads can get a chance to execute is to use yield in Java.
yield is a static method.
It doesn't say which other thread will get the CPU.
It is possible for the same thread to get back the CPU and start its execution again.
public class Solution9 {
public static void main(String[] args) {
yclass yy = new yclass ();
Thread t1= new Thread(yy);
t1.start();
for (int i = 0; i <3; i++) {
Thread.yield();
System.out.println("during yield control => " + Thread.currentThread().getName());
}
}
}
class yclass implements Runnable{
#Override
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println("control => " + Thread.currentThread().getName());
}
}
}
sleep()causes the thread to definitely stop executing for a given amount of time; if no other thread or process needs to be run, the CPU will be idle (and probably enter a power saving mode).
yield()basically means that the thread is not doing anything particularly important and if any other threads or processes need to be run, they should. Otherwise, the current thread will continue to run.
sleep() causes the thread to definitely stop executing for a given amount of time; if no other thread or process needs to be run, the CPU will be idle (and probably enter a power saving mode).
yield() basically means that the thread is not doing anything particularly important and if any other threads or processes need to be run, they should. Otherwise, the current thread will continue to run.
Both methods are used to prevent thread execution.
But specifically,
sleep():
purpose:if a thread don't want to perform any operation for particular amount of time then we should go for sleep().for e.x. slide show .
yield():
purpose:if a thread wants to pause it's execution to give chance of execution to another waiting threads of same priority.thread which requires more execution time should call yield() in between execution.
Note:some platform may not provide proper support for yield() . because underlying system may not provide support for preemptive scheduling.moreover yield() is native method.
I have a confusion. I read somewhere that Thread.yield() method causes the currently running thread to pause and give chance to remaining thread of "Same Priority".
Now always it is same priority threads executed or higher priority threads can also be executed. And if suppose currently running thread has some lock on some object, after executing yeild method will it give its lock?
When you call Thread.yield() the current thread pauses and allows the scheduler to run a different thread. Priorities are managed by the scheduler.
And no, of course not - you don't release any locks. Doing so would break synchronization.