Java Thread Scheduling
My notes say that there are two main categories of thread scheduling algorithms, preemptive and time sharing. I'd like to clear up exactly how these work in Java.
As I understand (and PLEASE correct me if I'm even slightly wrong!) preemptive allows a higher priority thread to take over the CPU from a lower priority thread when it enters the runnable state. Will it monopolize the CPU until an even higher priority thread comes along, or will it simply consume most of the CPU time, but lower priority threads will also get a chance to run? I'm assuming here that there are no calls to methods that will give up the CPU like yield() or sleep().
In time sharing, does a higher priority thread get a greater share of CPU time?
I'm guessing my explanation (well the question I've posed) for preemptive cannot be right as then it just seems the same as time sharing! But I'd like to be sure of the details.
And I suppose, how is this all implemented? Does the JVM or the OS schedule threads, or is that JVM implementation dependent?
First, I suspect that your notes are incorrect, and should be non-preemptive versus time-sharing (which is also known as preemptive). At least, that's how the breakdown went when I took an OS class several decades ago, and I doubt that it's changed.
In a non-preemptive thread (/process) model, each thread (/process) is granted sole use of the CPU until it explicitly relinquishes it. This is the model that you find in single-user operating systems such as the original Windows or Macintosh (as well as a bunch of minicomputer systems that predated them). A running process could explicitly yield()
its control of the processor, allowing another thread/process to run. Of course, there are many caveats to that, particularly regarding interrupt handling, but I'll leave the description there.
In a preemptive, aka timesharing model, the operating system may force a thread/process to yield the CPU (ie, "preempt" it). This can happen at any number of places, but in the simplest case the OS is called on every tick of a clock, and decides which process should get the CPU for the next tick of the clock. Again simplifying, the process with the highest priority gets to run; if there are multiple processes at the same priority, a least-recently-run algorithm generally decides.
But, regardless, for all modern Java implementations, it's the OS that decides when (and where) a thread should run, not the JVM.
Not a thread expert but letting a thread run indefinitely can lead to starvation. You still give lower priority ones some time. I believe time sharing gives all threads basically the same amount. These notes may help a little bit.
From said notes:
Non-preemptive Scheduling: The current process releases the CPU either by terminating or by switching to the waiting state. (Used in MS Windows family)
Preemptive Scheduling: The current process needs to involuntarily release the CPU when a more important process is inserted into the ready queue or once an allocated CPU time has elapsed. (Used in Unix and Unix-like systems)
Actually, a thread is an abstract concept. It is just an atomic process which should be executed. By atomic, I mean a process which, if you stop it (eg because it is too long and you want to execute another one) you need to store its current state and restore it before to continue the execution of the process. Now, what is in the process depends on what you want it to be. In C for instance, a language which were designed to build OSs if I remember well, a process is basically a program. This program can ask to the system to run other programs, or to fork itself to run a clone (by using the fork() function). Whether it is a different program or a clone, it is anyway a different process, which should be executed atomically. In C, a thread is a program. In Java, a thread is a class extending Thread. In C, you start a thread/program by executing its main() function, in Java you run a thread/class by executing its run() method. That is for the thread concept alone. It is just a generic name for the program or the Thread instance which is executed.
Nowaday, computers need to execute many stuff in parallel. It leads to manage several threads at the same time. Here comes the thread pool: it is a list of threads to execute. Nothing more. A simple list. But with that, you have the scheduler: you have a given number of "processors", and you need to decide which threads to execute on them, but you cannot execute more threads than you have "processors". The scheduler strategy should be designed to save as much time as possible, and this depends on the content and the dependencies of the threads. Different strategies can be used, like a balanced execution time, round robin, priorities, etc.
I put "processors" in quotes because I mean here "computing units". It can be the physical processor of the computer, or CPU, which nowaday has between 2 and 8 cores usually (meaning it can run 2-8 threads at the same time), and execute CPU instructions (typically RISC). It can be the processors of the graphic card, or GPU, which has several dozens or hundreds of cores, but use a different set of instructions. Iit can also be the processor from the Java Virtual Machine or JVM, which can run a single thread only and use its own set of instructions (bytecode). The main difference between the JVM and the two previous ones is that the CPU and GPU interact directly with the hardware, without intermediaries, while the JVM translate its own bytecode into RISC instructions and ask to the CPU to execute them.
The CPU uses its own scheduler to execute its threads (bloc of RISC instructions, not only one). Let call it a "system thread". But when you program in Java, your execution environment is not the system, it is the JVM, which provides you an abstraction of the system (this is how you can run a Java program on any machine without caring about the system underneath). This means that you are not allowed to communicate with the system directly, so Java provides you a way to deal with threads at its own level, allowing you to create the threads (new Thread()) and provide them to a scheduler (SwingUtilities, Executors, etc.). How your Java threads are translated into system threads, and how your Java scheduler is used to replace the system scheduler, is the job of the JVM.
So when you speak about a thread in Java, you don't speak about a thread at the system level. This is the JVM which will interact with the system in order for you to have a similar behaviour. But your Java thread are not managed by the CPU, thus your ability to ask for a specific scheduling strategy, independently of the scheduling strategy of the CPU.
How is Thread scheduling in Java done?. Available from: https://www.researchgate.net/post/How_is_Thread_scheduling_in_Java_done [accessed May 22, 2017].
链接地址: http://www.djcxy.com/p/84822.html上一篇: 特殊情况调度
下一篇: Java线程调度