Java Concurrency and Lock Design Implementation Details (1) - Java Thread Status

From this article, we officially entered the world of Java concurrency and locks.

What is concurrency? What is a lock? In Java, tasks are generally executed in units of threads. When multiple threads access a shared resource at the same time during the execution of the task, we call this phenomenon concurrency. When acquiring this shared resource concurrently, there will be no state inconsistency or mutual influence. This shared resource needs to be restricted. Only the thread that passes this restriction can obtain the control and operation rights of this shared resource, and the lock is for the resource. Restriction, access to the resources wrapped by the lock can only be obtained after the lock is obtained.

The competition for locks involves the state switching of threads. Therefore, here, we first need to know which states of threads in Java and how to switch between these states.

Let's first look at the definition of thread state in JDK1.7, which can be seen in the java.lang.Thread class. This class contains an internal enumeration class State, which defines some states of the thread, as follows:

public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }

From this enumeration, we can see that it is divided into seven states: NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, and TERMINATED. In the analysis here, I only select the more important and critical states for analysis.

The state switching between threads is shown in the following figure:


The various thread states are described below.

(1) New state (initial state)

A class that implements the Runnable interface or inherits Thread can get a thread class. If it is a class that implements the Runnable interface, then this class needs to be passed as a parameter to the Thread class before it can be started as a thread.

(2) Operational state

When the thread in the new state calls the start() method, it enters the runnable state. Entering the runnable state just means that the thread has the opportunity to enter the running state, and only after getting the running time slice can it actually get running and enter the running state.

When the time slice is used up or the yield() method is called, the running thread will enter the runnable state.

For threads in the lock pool, if they get the lock, they will re-enter the runnable state.

(3) Running state

Thread scheduling will select a thread from the runnable thread pool according to certain rules and assign it a time slice to run, which is also the only way to enter the running state.

(4) End (termination) state

When the thread runs the run() method or the main thread terminates, the thread will enter the termination state. Of course, if an exception is encountered during the thread running process, it will also enter the termination state. Calling the start() method on a terminated thread will throw a java.lang.IllegalThreadStateException.

(5) Blocking state

When a running thread (a) needs to wait until other resources are ready (b) calls the Thread.sleep() method to sleep for a period of time (c) other threads running in the thread call the join() method, then the current thread will enter the blocking condition. For a thread in a blocked state, if (a) the waiting resource is ready (b) the sleep time has come (c) other threads calling join() have ended, the current thread will enter the runnable state.

(6) Lock pool status

When the current thread competes for a lock and the lock is acquired by other threads, the current thread enters the lock pool state.

(7) Waiting queue

Before calling the wait(), notify() methods of obj, the obj lock must be obtained, that is, it must be written in the synchronized(obj) code segment. When the wait() method is called, the current thread will release the currently acquired lock and move the current thread into the waiting queue. When other threads call the notify() or notifyAll() method of this obj, the current thread will be notified and enter the lock pool.

The operation steps and diagrams related to the waiting queue are as follows:


So far, the thread state and switching between states in Java are roughly finished, thank you.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325915495&siteId=291194637