Interview shock: talk about thread life cycle and transformation process?

Posted by hongco on Fri, 18 Feb 2022 15:29:27 +0100

The life cycle of a thread refers to the whole process from creation to destruction. Generally, there are five kinds of thread life cycles:

Initial state
Operational status
running state
Dormant state
Termination status
Their state transitions are shown in the following figure:

Java thread lifecycle
The life cycle of Java thread is different from that mentioned above. It has the following six states:

NEW (initialization status)
RUNNABLE (RUNNABLE / running state)
BLOCKED
WAITING (unlimited WAITING state)
TIMED_WAITING (time limited waiting state)
TERMINATED
We can find these six states in the source code of Thread, as shown below:

Of course, you can also use Java code to print all thread states, as shown in the following code:

for (Thread.State value : Thread.State.values()) {
    System.out.println(value);
}
Copy code

The execution results of the above procedures are shown in the figure below:

Life cycle transformation
Let's talk about the Java thread life cycle.

1. From NEW to RUNNABLE
When we create a thread, that is, new Thread, the thread is in NEW state, as shown in the following code:

// Create thread
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        // ...
    }
});
// Get thread status
Thread.State state = thread.getState();
System.out.println(state);
Copy code

The execution results of the above procedures are shown in the figure below:

However, after calling the start method of the thread, the state of the thread changes from NEW to RUNNABLE, as shown in the following code:

// Create thread
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        // Gets the thread currently executing
        Thread currThread = Thread.currentThread();
        // Get thread status
        Thread.State state = currThread.getState();
        // Print thread status
        System.out.println(state);
    }
});
thread.start()

;
Copy code
The execution results of the above procedures are shown in the figure below:

2. From RUNNABLE to BLOCKED
When the code in the thread is queued to execute synchronized, the thread will change from RUNNABLE state to BLOCKED state, as shown in the following code:

// Create thread
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            // Wait 100 milliseconds
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Queue lock");
        synchronized (ThreadStates.class) {
        }
    }
});
thread.start();
// Let the main thread get the lock first
synchronized (ThreadStates.class) {
    // Get thread status
    Thread.State state = thread.getState();
    // Print thread status
    System.out.println("Get thread status for the first time:" + state);
    // Sleep for 1s
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    // Get thread status again
    state = thread.getState();
    // Print thread status
    System.out.println("Get thread status for the second time:" + state);
}
Copy code

The execution results of the above procedures are shown in the figure below:

When the thread obtains the synchronized lock, it will change from the BLOCKED state to the RUNNABLE state.

3. From RUNNABLE to waiting
After the thread calls the wait() method, it will change from the RUNNABLE state to the WAITING unlimited wait state, as shown below:

// Create thread
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        synchronized (this) {
            try {
                // Thread sleep
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
});
// Start thread
thread.start();
// Get thread status
Thread.State state = thread.getState();
// Print thread status
System.out.println("Get thread status for the first time:" + state);
// Sleep for 1s
try {
    Thread.sleep(1000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
// Get thread status
state = thread.getState();
// Print thread status
System.out.println("Get thread status for the second time:" + state);
Copy code

The execution results of the above procedures are shown in the figure below:

When the notify/notifyAll method is called, the thread will change from WAITING state to RUNNABLE state, as shown in the following code:

Object lock = new Object();
// Create thread
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        synchronized (lock) {
            try {
                // Thread sleep
                lock.wait();
                // Get current thread status
                Thread.State state = Thread.currentThread().getState();
                // Print thread status
                System.out.println("Get thread status:" + state);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
});
// Start thread
thread.start();
// Get thread status
Thread.State state = thread.getState();
// Print thread status
System.out.println("Get thread status for the first time:" + state);
// Sleep for 1s
try {
    Thread.sleep(100);
} catch (InterruptedException e) {
    e.printStackTrace();
}
// Get thread status
state = thread.getState();
// Print thread status
System.out.println("Get thread status for the second time:" + state);

// Wake up thread
synchronized (lock) {
    lock.notify();
}
Copy code

The execution results of the above procedures are shown in the figure below:

4. From RUNNABLE to TIMED_WATTING
When calling the wait method with timeout, such as sleep(xxx), the thread will change from the RUNNABLE state to TIMED_WAITING has time limit status, as shown in the following code:

// Create thread
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
});
// Start thread
thread.start();
// Get thread status
Thread.State state = thread.getState();
// Print thread status
System.out.println("Get thread status for the first time:" + state);
// Sleep for 1s
try {
    Thread.sleep(100);
} catch (InterruptedException e) {
    e.printStackTrace();
}
// Get thread status
state = thread.getState();
// Print thread status
System.out.println("Get thread status for the second time:" + state);
Copy code

The execution results of the above procedures are shown in the figure below:

When the timeout period is exceeded, the thread will start from timed_ The waiting state changes to the RUNNABLE state, and the implementation code is as follows:

// Create thread
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
            // Get current thread status
            Thread.State state = Thread.currentThread().getState();
            // Print thread status
            System.out.println("Get thread status:" + state);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
});
// Start thread
thread.start();
// Get thread status
Thread.State state = thread.getState();
// Print thread status
System.out.println("Get thread status for the first time:" + state);
// Sleep for 1s
try {
    Thread.sleep(100);
} catch (InterruptedException e) {
    e.printStackTrace();
}
// Get thread status
state = thread.getState();
// Print thread status
System.out.println("Get thread status for the second time:" + state);
Copy code

The execution results of the above procedures are shown in the figure below:

5.RUNNABLE to TERMINATED
After the thread is executed, it will change from the RUNNABLE state to the TERMINATED destruction state, as shown in the following code:

// Create thread
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        // Get current thread status
        Thread.State state = Thread.currentThread().getState();
        // Print thread status
        System.out.println("Get thread status:" + state);
    }
});
// Start thread
thread.start();
// Wait for 100ms until the thread is finished
Thread.sleep(100);
// Get thread status
Thread.State state = thread.getState();
// Print thread status
System.out.println("Thread status:" + state);
Copy code

The execution results of the above procedures are shown in the figure below:

summary
There are six kinds of thread life cycles in Java: NEW, RUNNABLE, BLOCKED, WAITING and TIMED_WAITING, TERMINATED. The conversion process of thread life cycle is shown in the following figure:

last
If you think this article is a little helpful to you, give it a compliment. Or you can join my development exchange group: 1025263163 learn from each other, and we will have professional technical Q & A to solve doubts

If you think this article is useful to you, please click star: http://github.crmeb.net/u/defu esteem it a favor!

PHP learning manual: https://doc.crmeb.com
Technical exchange forum: https://q.crmeb.com

Topics: PHP