Talking about the thread state of Java

There are 6 types of thread states in Java, as follows:

1. Initial (NEW): A thread object is newly created, but the start() method has not been called yet.
2. RUNNABLE: The two states of ready (ready) and running (running) are collectively called "running" in Java threads.
After the thread object is created, other threads (such as the main thread) call the object's start() method. Threads in this state are in the runnable thread pool, waiting to be selected by thread scheduling to obtain the right to use the CPU, and are in the ready state (ready) at this time. A thread in the ready state becomes a running state after obtaining a CPU time slice.
3. Blocked (BLOCKED): Indicates that the thread is blocked on the lock.
4. Waiting (WAITING): The thread entering this state needs to wait for other threads to make some specific actions (notification or interrupt).
5. TIMED_WAITING: This state is different from WAITING, it can return by itself after a specified time.
6. Termination (TERMINATED): Indicates that the thread has been executed.

These 6 states are defined in the State enumeration of the Thread class, and you can view the source code for one-to-one correspondence.

  The state diagram of the thread:

1. Initial state

A thread class can be obtained by implementing the Runnable interface and inheriting from Thread. When an instance of new comes out, the thread enters the initial state.

2.1. Ready state
Ready state only means that you are qualified to run. If the scheduler does not pick you up, you will always be in ready state.
The start() method of the thread is called, and the thread enters the ready state.
The sleep() method of the current thread ends, and the join() of other threads ends, waiting for the user's input to be completed, and a thread gets the object lock, and these threads will also enter the ready state.
When the current thread time slice is used up, the yield() method of the current thread is called, and the current thread enters the ready state.
After the thread in the lock pool gets the object lock, it enters the ready state.
2.2. Running state The state of the
thread when the thread scheduler selects a thread from the runnable pool as the current thread. This is also the only way for a thread to enter the running state.

3. Blocked state

The blocking state is the state when the thread is blocked when it enters the method or code block modified by the synchronized keyword (acquisition of the lock).

4. Wait

Threads in this state will not be allocated CPU execution time, they have to wait to be awakened explicitly, otherwise they will wait indefinitely.

5. Overtime waiting
. Threads in this state will not be allocated CPU execution time, but there is no need to wait indefinitely for being awakened by other threads. They will automatically wake up after a certain period of time.

6. Termination state
When the thread's run() method completes, or the main thread's main() method completes, we consider it terminated. This thread object may be alive, but it is no longer a separate thread of execution. Once the thread is terminated, it cannot be reborn.
Calling the start() method on a terminated thread will throw a java.lang.IllegalThreadStateException.

Comparison of common threading methods

The difference between sleep and wait

What we all know is that both sleep and wait will cause the thread to suspend execution. The following will analyze the individual differences from several aspects.

For the sleep() method, we must first know that the method belongs to the Thread class. The wait() method belongs to the Object class. The sleep() method causes the program to suspend execution for a specified time, giving up the cpu to other threads, but its monitoring state is still maintained, and it will automatically resume its running state when the specified time is up. In the process of calling the sleep() method, the thread will not release the object lock. When the wait() method is called, the thread will give up the object lock and enter the waiting lock pool waiting for this object. Only after calling the notify() method for this object, the thread enters the object lock pool and prepares to acquire the object lock and enter the running state. The location of use is different: For wait, the lock must be acquired before it is used, so it must be placed in synchronized code, or executed in synchronization, but for sleep, it can be placed in any place for execution. Sleep needs to catch exceptions. These are not needed for wait notify etc.

The difference between start and run

The start() method starts the thread, which truly realizes multi-threaded operation. At this time, there is no need to wait for the execution of the run method body code to complete, you can continue to execute the following code directly. Start a thread by calling the start() method of the Thread class. At this time, the thread is in a ready state and is not running. For multithreading, only when the start method is called in a real sense can it be regarded as a start of the thread. The method run() is called the thread body, which contains the content of the thread to be executed. The thread enters the running state and starts to run the code in the run function. The Run method ends, and this thread terminates. Then the CPU schedules other threads

join()

The join() method makes the thread that called the method finish executing before that, that is, it waits for the thread of the method to finish executing before continuing. Note that this method also needs to catch exceptions. That is to say, let the thread execute the code behind the join method after executing the RUN() method, that is to say, the two threads can be merged to realize the synchronization function, and the threads are executed in sequence.

yield()

This method is similar to sleep() except that the user cannot specify the length of the pause, and the yield() method can only give threads of the same priority a chance to execute. As mentioned earlier, sleep will not release the lock identification yield nor will it release the lock identification.

In fact, the yield() method corresponds to the following operations; first check whether there are currently threads with the same priority in the same runnable state, if so, transfer the CPU ownership to the secondary thread, otherwise continue to run the original thread, so The yield() method is called "yielding", and it gives up the running opportunity to other threads of the same level.

The sleep method allows lower-priority threads to get a chance to run, but when the yield() method is executed, the current thread is still in a runnable state, so it is impossible to allow lower-priority threads to obtain CPU ownership at this time. In a running system, if the higher-priority thread does not call the sleep method and is not blocked by I/O, then the lower-priority thread can only wait for all higher-priority threads to finish before they have a chance to run . Yield() just returns the current thread to the executable state. All threads that execute yield() may be executed immediately after entering the executable state, so the yield() method can only make the threads of the same priority execute Opportunity.

 

wait()和notify()、notifyAll()

These three methods are used to coordinate the access of shared data by multiple threads, so they must be used in the synchronized statement block. The synchronized keyword is used to protect shared data and prevent other threads from accessing shared data, but the flow of the program is very inflexible. How can other threads have the opportunity to access shared data before the current thread has exited the synchronized data block? What? At this time, these three methods are used for flexible control. The wait() method causes the current thread to suspend execution and release the object lock flag, so that other threads can enter the synchronized data block, and the current thread is put into the object waiting pool. When the notify() method is called, an arbitrary thread will be removed from the waiting pool of the object and placed in the lock flag waiting pool. Only the threads in the lock flag waiting pool can acquire the lock flag; if there is no thread in the lock flag waiting pool , Then notify() does not work. notifyAll() removes all threads waiting for that object from the object waiting pool and puts them in the lock flag waiting pool.

Wait, notify the exact process of blocking wake-up? Where to block and where to wake up? Why should it appear in a synchronous code block, and why should it be in a while loop?

Common void wait methods are

wait (long timeout) wait(). For methods without parameters: the current thread is in a waiting state before the notify method or nofifyall method of this object is called by other threads.

For a function with parameters, if the above two conditions are true, it will also be in a waiting state before the time expires.

For after the wait method is executed. The thread will release the occupied lock identifier so that other synchronized data in the object where the thread is located can be used by other threads. Because you need to process and operate the lock flag when you execute wait and notify(), one is to release the lock and the other is to add the lock, so it needs to be called in the synchronized function or function block, if it is not in the function or function block Although it is said that it can be compiled and passed. But there will be an IllegalMonitorStateException.

 

Why are the wait, notify and notifyAll methods not in the thread class?

One obvious reason is that the locks provided by Java are object-level rather than thread-level. Each object has a lock and is obtained through a thread. Since wait notify and notifyAll are lock-level operations, they are defined in Object Because the lock belongs to the object in the class.

 

With regard to the basic knowledge of thread status, I have summarized so much today. I don't have a thorough understanding of this one, so I will learn more later.

 

Guess you like

Origin blog.csdn.net/huzhiliayanghao/article/details/106503707