Thread implementation
In Java, run method indicates the task to be completed for threads. There are two techniques to provide run methods for threads:
1. Inherit the Thread class and override its run method. Then create an object of this subclass and call the start() method.
2. Define the class that implements the Runnable interface and then implement the run method. The object of this class is passed as a parameter when creating Thread, and then the start() method is called.
The Thread class is a class specially used to create threads and operate on threads. When a class inherits the Thread class, the class is called a thread class.
Both methods require the execution of the start() method of the thread to allocate the necessary system resources to the thread, schedule the thread to run and execute the run() method of the thread.
The start() method is the only way to start the thread. The start() method first prepares the system resources for the execution of the thread, and then calls the run() method. A thread can only be started once, and it is illegal to start again.
The thread's work is put into the run() method, that is, all the things we want this thread to do. By default, the run() method does nothing.
In specific applications, which method to construct threads depends on the situation. Generally, when a thread has inherited another class, it should be constructed in the second way, that is, implementing the Runnable interface.
Here are two examples to illustrate two implementation methods of threads. Each example has two threads:/
public class ThreadTest1{ public static void main(String[] args) { Thread1 thread1 = new Thread1(); Thread2 thread2 = new Thread2(); thread1.start(); t hread2.start(); }}class Thread1 extends Thread{ @Override public void run() { for (int i = 0; i < 100; ++i) { System.out.println("Hello World: " + i); } }}class Thread2 extends Thread{ @Override public void run() { for (int i = 0; i < 100; ++i) { System.out.println("Welcome: " + i); } }}public class ThreadTest2{ public static void main(String[] args) { // Another method of implementation of threads can also use the anonymous inner class Thread thread1 = new Thread(new MyThread1()); thread1.start(); Thread thread2 = new Thread(new MyThread2()); thread2.start(); }}class MyThread1 implements Runnable{ @Override public void run() { for (int i = 0; i < 100; ++i) { System.out.println("Hello: " + i) ; } }}class MyThread2 implements Runnable{ @Override public void run() { for (int i = 0; i < 100; ++i) { System.out.println("Welcome: " + i); } } }
Thread class analysis
The Thread class also implements the Runnable interface, so it implements the run() method in the interface.
When generating a thread object, if no name is specified for it, the name of the thread object will be in the form of: Thread-number, which is an automatically increased number and is shared by all Thread objects because it is a static member variables.
When using the first method (the way of inheriting Thread) to generate thread objects, we need to override the run() method because the run() method of the Thread class does nothing at this time.
When using the second method (the way to implement the Runnable interface) to generate thread objects, we need to implement the run() method of the Runnable interface, and then use new Thread(new MyRunnableClass()) to generate thread objects (MyRunnableClass has implemented Runnable ) At this time, the run() method of the thread object will call the run() method of MyRunnableClass.
Stop thread
The demise of a thread cannot be done by calling the stop() command, but let the run() method end naturally. The stop() method is unsafe and has been abandoned.
Recommended way to stop threads: set a flag variable, which is a loop in the run() method. This flag variable controls whether the loop continues to execute or jumps out; if the loop jumps out, the thread ends.
As shown in the code example:
public class ControlThreadTest{ MyThreadClass r = new MyThreadClass(); Thread t = new Thread(r); public void startThread() { t.start(); } public vo id stopThread() { r.stopRunning(); }}class MyThreadClass implements Runnable{ private boolean flag = true; @Override public void run() { while (flag) { System.out.println("Do something."); } } public void stopRunning() { flag = false; }}
Thread life cycle and priority thread life cycle
Thread life cycle: The process from creation to demise of a thread.
The following figure shows the various states in the thread life cycle:
The life cycle of a thread can be divided into four states:
1. Create status:
When a new thread object is created with the new operator, the thread is in the created state.
A thread in the created state is just an empty thread object and the system does not allocate resources to it.
2. Runable status:
The start() method of the execution thread will allocate the necessary system resources to the thread, arrange its operation, and call the thread body - run() method, so that the thread is in a runnable state (Runnable).
This state is not a running state, because the thread may not actually run.
3. Not run state:
When the following events occur, the thread in the running state will be transferred to the unrunable state:
The sleep() method was called;
The thread calls the wait() method to wait for the specific conditions to be satisfied;
Thread input/output blocking.
Return to the runnable state:
The thread in sleep state has passed after the specified time;
If the thread is waiting for a certain condition, another object must notify the waiting thread condition change through the notify() or notifyAll() method;
If the thread is blocked due to input and output, wait for the input and output to complete.
4. Death state:
When the thread's run() method is executed, the thread naturally dies.
Thread priority
1. Priority and settings of threads
The priority of threads is to facilitate the system's scheduling of threads in a multi-threaded environment, and threads with high priority will be executed first.
The priority setting of a thread follows the following principles:
When a thread is created, the child inherits the parent's priority.
After the thread is created, the priority can be changed by calling the setPriority() method.
The priority of the thread is a positive integer between 1-10.
1- MIN_PRIORITY
10-MAX_PRIORITY
5-NORM_PRIORITY
If nothing is set, the default value is 5.
However, the priority of the thread cannot be determined by the execution order of the thread.
2. Thread scheduling strategy
The thread scheduler selects the thread with the highest priority to run. However, if the following occurs, the thread is terminated:
The yield() method is called in the thread body, giving up the CPU occupation.
The sleep() method is called in the thread body to make the thread fall asleep.
Threads are blocked due to I/O operations.
Another thread with higher priority appears.
In a system that supports time slices, the time slices of the thread run out.