[Understand Java multithreading 2] multi-thread scheduling and daemon, java Multithreading
As mentioned in the previous article, the operating system will select the highest priority for scheduling for all threads in the ready state, is it true that a thread with a higher priority must be executed first than a thread with a lower priority? How is the thread priority defined? This article is about to address this issue! Welcome to my personal blog homepage www.anycodex.com
1. thread priority
In Java, the thread priority ranges from 0 to 10. A larger integer indicates a higher priority.
- Several macro definitions:
MAX_PRIORITY 10, highest priority
MIN_PRIORITY 1, minimum priority
NORM_PRIORITY 5, default priority
SetPriority (int x), set the thread priority
GetPriority () to get the thread priority
Since there is a priority between threads, is it true that a thread with a higher priority must be executed first than a thread with a lower priority? Is the answer true. It can only be said that a thread with a higher priority is more likely to obtain the CPU, but this does not mean that it will be executed first.
Dear friends, let's take a look at the code example below (~ O ~)~ ZZ
Package net. mindview. util; // Step 1: implement the Runnable interface class MyThreadRunning implements Runnable {// Step 2: override the run method public void run () {for (int I = 0; I <= 3; I ++) {System. out. println (Thread. currentThread (). getName () ;}} public class MyThread {public static void main (String [] args) {// Step 3: instantiate the custom Thread class Object MyThreadRunning mtr1 = new MyThreadRunning (); MyThreadRunning mtr2 = new MyThreadRunning (); MyThreadRunning mtr3 = new MyThreadRunning (); // Step 4: instantiate a Thread Class Object and pass in the Custom Thread class object as a parameter. The following parameter is Thread thread1 = new Thread (mtr1, "Thread 1 is running"); Thread thread2 = new Thread (mtr2, "Thread 2 is running"); Thread thread3 = new Thread (mtr3, "Thread 3 is running "); thread1.setPriority (Thread. MAX_PRIORITY); thread2.setPriority (Thread. MIN_PRIORITY); thread3.setPriority (Thread. NORM_PRIORITY); // Step 5: Call the start method to start the thread thread1.start (); thread2.start (); thread3.start ();}}
Running result:
Thread 1 is running
Thread 1 is running
Thread 2 is running
Thread 1 is running
Thread 3 is running
Thread 3 is running
Thread 3 is running
Thread 3 is running
Thread 1 is running
Thread 2 is running
Thread 2 is running
Thread 2 is running
Dangdang, do you understand? A thread with a higher priority may not be executed first? However, CPU scheduling is possible for a relatively large one. You may ask, if you have set the priorities, you still cannot ensure that the thread is executed in the order I want. What can I do? Well, after reading the following content, you can learn some tricks. It is our thread scheduling.
2. Thread Scheduling
With regard to thread scheduling, we need to know that only good scheduling can play a good role in system performance and improve program execution efficiency. However, how well the program is scheduled cannot accurately control the running of the program. Generally, we use thread scheduling methods such as sleep, yield, and join. Let's take a look at it one by one!
Sleep () method, sleep as explained in English, sleep. When a program enters the sleep state, it will hand over the CPU resources to other threads, and when the sleep time arrives, the program automatically enters the ready state from the blocking state, waiting for the scheduling of CPU resources. The sleep () parameter is millisecond-level. For example, sleep (1000) is used to sleep the thread for 1 s. InterruptedException must be caught when this method is called. See the following code.
Package net. mindview. util; // Step 1: implement the Runnable interface class MyThreadRunning implements Runnable {// Step 2: override the run method public void run () {for (int I = 0; I <= 3; I ++) {System. out. println (Thread. currentThread (). getName (); try {Thread. sleep (1000);} catch (InterruptedException e) {// TODO Auto-generated catch block e. printStackTrace () ;}}} public class MyThread {public static void main (String [] args) {// Step 3: instantiate the custom Thread class Object MyThreadRunning mtr1 = new MyThreadRunning (); MyThreadRunning mtr2 = new MyThreadRunning (); MyThreadRunning mtr3 = new MyThreadRunning (); // Step 4: instantiate a Thread Class Object and pass in the Custom Thread class object as a parameter. The following parameter is Thread thread1 = new Thread (mtr1, "Thread 1 is running"); Thread thread2 = new Thread (mtr2, "Thread 2 is running"); Thread thread3 = new Thread (mtr3, "Thread 3 is running "); // Step 5: Call the start method to start the thread thread1.start (); thread2.start (); thread3.start ();}}
Running result:
Thread 2 is running
Thread 3 is running
Thread 1 is running
Thread 3 is running
Thread 2 is running
Thread 1 is running
Thread 2 is running
Thread 1 is running
Thread 3 is running
Thread 3 is running
Thread 2 is running
Thread 1 is running
It can be seen from the running results that the thread cannot precisely control the sequence. Each running result may be different.
The yield method is just like the English meaning, that is, concession. Pause the current thread to get the CPU running time and enter the ready state, so that other threads can get the CPU time. However, it is meaningless or ineffective for preemptible operating systems.
Package net. mindview. util; // Step 1: implement the Runnable interface class MyThreadRunning1 implements Runnable {// Step 2: override the run method public void run () {for (int I = 0; I <= 3; I ++) {System. out. println (Thread. currentThread (). getName () ;}}// Step 1: implement the Runnable interface class MyThreadRunning2 implements Runnable {// Step 2. Override the run method public void run () {for (int I = 0; I <= 3; I ++) {System. out. println (Thread. currentThread (). getName (); Thread. yield () ;}} public class MyThread {public static void main (String [] args) {// Step 3: instantiate the custom Thread class Object MyThreadRunning1 mtr1 = new MyThreadRunning1 (); MyThreadRunning2 mtr2 = new MyThreadRunning2 (); // Step 4: instantiate a Thread Class Object and pass in the Custom Thread class object as a parameter. The following parameter is Thread thread1 = new Thread (mtr1, "Thread 1 is running"); Thread thread2 = new Thread (mtr2, "Thread 2 is running"); // Step 5: Call the start method to start Thread thread1.start (); thread2.start ();}}
Running result: if you do not add yield, the possible running result is:
Thread 1 is running Thread 1 is running
Thread 2 is running Thread 2 is running
Thread 1 is running Thread 1 is running
Thread 2 is running Thread 1 is running
Thread 1 is running Thread 1 is running
Thread 2 is running Thread 2 is running
Thread 1 is running Thread 2 is running
Thread 2 is running Thread 2 is running
From the running effect, we can see that thread 2 will give up CPU resources once every execution, but it is only possible to run the result.
The function of the join method may not be so simple in English. In fact, the function of the join method is to let one thread wait for the execution of another thread to complete and then continue execution. You can add a parameter in milliseconds of the long type. The maximum number of seconds to wait for the process to terminate. For example, thread. mt () is to execute other programs after the thread completes execution. Let's look at the following code:
Package net. mindview. util; // Step 1: Inherit the Thread class MyThreadRunning extends Thread {// constructor public MyThreadRunning () {super ("My Thread ");} // Step 2: override the run method public void run () {for (int I = 0; I <= 3; I ++) {System. out. println ("Create a thread" + getName () + I); try {sleep (1000);} catch (InterruptedException e) {// TODO Auto-generated catch block e. printStackTrace () ;}}} public class MyThread {public static voi D main (String [] args) {// Step 3: instantiate the custom Thread class Object MyThreadRunning mtr = new MyThreadRunning (); // Step 4: Call the start method to start the run method mtr. start (); try {mtr. join ();} catch (InterruptedException e) {// TODO Auto-generated catch block e. printStackTrace ();} System. out. println ("Have you finished mtr? I am the main thread. I want to print it. ");}}
Running result:
Create a thread, My Thread0
Create a thread, My Thread1
Create a thread, My Thread2
Create a thread, My Thread3
Mtr, are you finished? I am the main thread. I want to print it.
3. Daemon
Daemon is also called a background process. It is a thread that provides services for other threads. When the virtual machine detects that no user process has been executed, the JVM may exit even if there are background processes.
Related interfaces:
SetDaemon (boolean) sets a thread as a background process;
Thread. isDaemon () determines whether a Thread is a background process.
Let's look at the following code:
Package net. mindview. util; // Step 1. inherit from the Thread class public class MyThread {public static void main (String [] args) {Thread t1 = new MyCommon (); thread t2 = new Thread (new MyDaemon (); t2.setDaemon (true); // set it to the daemon Thread t2.start (); t1.start ();}} class MyCommon extends Thread {public void run () {for (int I = 0; I <5; I ++) {System. out. println ("thread 1" + I + "times! "); Try {Thread. sleep (7);} catch (InterruptedException e) {e. printStackTrace () ;}}} class MyDaemon implements Runnable {public void run () {for (long I = 0; I <9999999L; I ++) {System. out. println ("background Thread No." + I + "times! "); Try {Thread. sleep (7);} catch (InterruptedException e) {e. printStackTrace ();}}}}
Running result:
Thread 1 executes 0th times!
The background thread executes 0th times!
The background thread executes 1st times!
Thread 1 executes 1st times!
Thread 1 executes 2nd times!
The background thread executes 2nd times!
Thread 1 executes 3rd Times!
The background thread executes 3rd Times!
Thread 1 executes 4th times!
The background thread executes 4th times!
The background thread executes 5th times!
Students, can we see from the running results that the program has exited before the background thread has been executed completely.
The above is the second part about Java multithreading. To sum up, this article focuses on the scheduling of Java multithreading. Scheduling Methods include sleep, concession, and join. However, it should be clear that no matter how programmers schedule, they cannot implement precise thread control. At that time, good thread scheduling could improve the program running efficiency. Finally, we will talk about the daemon thread, that is, the background thread. If the virtual machine detects that no user thread is running, it will exit regardless of whether there is any background thread. Well, that's all. Have you mastered it? In the following article, we will learn about the classic issues, thread synchronization issues such as producers and consumers, and how to refresh and refresh the fuel. It is not complete ~~~