Home  >  Article  >  Java  >  What are the 6 states and life cycles of Java threads?

What are the 6 states and life cycles of Java threads?

王林
王林forward
2023-05-02 12:07:061438browse

    1. Thread state (life cycle)

    A thread can only be in one state at a given point in time.

    Threads can have the following 6 states:

    • New (newly created): unstarted thread;

    • Runnable (Runnable): A runnable thread that needs to wait for operating system resources;

    • Blocked (Blocked): A thread that is blocked while waiting for the monitor lock;

    • Waiting (waiting): waiting for the wake-up state, waiting indefinitely for another thread to wake up;

    • Timed waiting (timed waiting): waiting within the specified waiting time A thread that another thread performs an operation on;

    • Terminated: A thread that has exited.

    To determine the current state of a thread, you can call the getState method

    Thread state relationship diagram

    Note: dotted box (all uppercase English) status is the Java thread status.

    What are the 6 states and life cycles of Java threads?

    2. Operation thread status

    2.1. New creation status (NEW)

    means that after the instantiation of the thread is completed, the thread is not started status.

    Threads can be created in three ways

    • Override the Thread class run() method

    • Implement the Runnable interface

    • Implementing the Callable interface

    A simple example summarizes three methods

    public class Demo {
    
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            /**
             * 1.直接重写run() 或继承Thread类再重写run()
             */
            Thread thread = new Thread() {
                @Override
                public void run() {
                    System.out.println("Thread");
                }
            };
            // 开启线程
            thread.start();
    
            /**
             * 2.lambda、内部类或线程类方式实现Runnable接口,实现run()方法
             * 再交给Thread 类
             */
            Thread runThread = new Thread(() -> {
                System.out.println("Runnable");
            });
            // 开启线程
            runThread.start();
    
            /**
             * 3.lambda、内部类或线程类方式实现Callable接口,实现call()方法
             * 再交给Thread 类:FutureTask本质也是Runnable实现类
             */
            FutureTask<String> futureTask = new FutureTask<String>(() -> {
                System.out.println("Callable");
                return "CallableThread";
            });
            Thread callThread = new Thread(futureTask);
            // 开启线程
            callThread.start();
            // 获取call()方法的返回值
            String s = futureTask.get();
            System.out.println("call()方法的返回值:"+s);
        }
    
    }

    Do not rewrite run() or call() The method directly instantiates the thread created by the Thread class has no practical significance;

    Only threads created in the Callable method can obtain the return value of the thread.

    2.2. Runnable state (RUNNABLE)

    This state refers to the state entered after the thread instantiates the object and calls the start() method. The thread is in a runnable state, and if there are resources such as a processor, the program can be executed.

    This state contains two steps at the operating system level: thread ready and thread running, but in the Java thread state, these two steps are collectively called Runnable (runnable) state.

    The thread changes from the ready state to the running state. The key point is to see whether your thread has grabbed the CPU resource (CPU time slice). Whoever grabs it will run it, and if it doesn't grab it, wait. Because the CPU time slice (execution time) is very short, about ten milliseconds, the time for thread switching is very short, and the time for the ready state to change to the running state is also very short. This state is almost invisible during development. Changes, so in Java, the two are regarded as a whole, focusing on whether the thread can run and distinguishing it from other states, further simplifying the development of threads. If your program needs to run for a long time (such as writing an infinite loop) and the execution is not completed within a CPU time slice, then your thread will have to grab the next CPU time slice. Only after it has grabbed it can it continue to execute the program. If it has not grabbed it, it can continue to execute the program. Then you need to continue grabbing until the program execution in the thread is completed.

    In fact, you should have seen this scenario before. For example, when multiple threads execute the same program and print logs to the same file, the logs of different threads will be mixed together, which is not conducive to troubleshooting. question. Common methods to solve this problem are: first, print the log to different files in different threads; second, save the log information into a string object, and print the log information to the file all at once at the end of the program. The second method is to use a time slice of the CPU to complete the printing of log information.

    Note: The program can only call the start() method on threads in the newly created state. Do not call the start() method on threads in the non-newly created state. This will cause an IllegalThreadStateException exception.

    2.3. Blocked state (BLOCKED)

    The thread is in a waiting for monitor lock and is blocked. One thread acquired the lock but did not release it. Other threads also came to acquire the lock, but found that they could not acquire the lock and entered the blocked state.

    The blocked state only exists under concurrent access by multiple threads, which is different from the latter two types of blocking caused by the thread itself entering "waiting".

    Enter state

    • Enter synchronized code block/method

    • No lock obtained

    Exit status

    • Obtained monitor lock

    2.4. Wait Wake-up state (WAITING)

    The whole process is like this: the thread first acquires the object lock in the synchronization method of an object; when the wait method is executed, the thread will release the object lock, and the thread is put Enter the waiting queue of this object; wait for another thread to acquire the lock of the same object, and then wake up the thread in the object's waiting queue through the notify() or notifyAll() method.

    It can be known from the entire process that

    wait (), notify () and notifyAll () methods need to obtain the lock before the thread can continue execution, so these three methods are required Place it in a synchronized code block/method for execution, otherwise an exception will be reported: java.lang.IllegalMonitorStateException.

    在同步代码块中,线程进入WAITING 状态时,锁会被释放,不会导致该线程阻塞。反过来想下,如果锁没释放,那其他线程就没办法获取锁,也就没办法唤醒它。

    进入状态

    • object.wait()

    • thread.join()

    • LockSupport.park()

    退出状态

    • object.notify()

    • object.notifyall()

    • LockSupport.unpark()

    2.5.计时等待状态(TIMED_WAITING)

    一般是计时结束就会自动唤醒线程继续执行后面的程序,对于Object.wait(long) 方法还可以主动通知唤醒。

    注意:Thread类下的sleep() 方法可以放在任意地方执行;而wait(long) 方法和wait() 方法一样,需要放在同步代码块/方法中执行,否则报异常:java.lang.IllegalMonitorStateException。

    进入状态

    • Thread.sleep(long)

    • Object.wait(long)

    • Thread.join(long)

    • LockSupport.parkNanos(long)

    • LockSupport.parkNanos(Object blocker, long nanos)

    • LockSupport.parkUntil(long)

    • LockSupport.parkUntil(Object blocker, long deadline)

    注:blocker 参数为负责此线程驻留的同步对象。

    退出状态

    • 计时结束

    • LockSupport.unpark(Thread)

    • object.notify()

    • object.notifyall()

    2.6.终止(TERMINATED)

    线程执行结束

    • run()/call() 执行完成

    • stop()线程

    • 错误或异常>>意外死亡

    stop() 方法已弃用。

    3.查看线程的6种状态

    通过一个简单的例子来查看线程出现的6种状态。

    案例

    public class Demo3 {
        private static Object object ="obj";
        
        public static void main(String[] args) throws InterruptedException {
    
            Thread thread0 = new Thread(() -> {
                try {
                    // 被阻塞状态(BLOCKED)
                    synchronized (object){
                        System.out.println("thread0 进入:等待唤醒状态(WAITING)");
                        object.wait();
                        System.out.println("thread0 被解除完成:等待唤醒状态(WAITING)");
                    }
                    System.out.println("thread0 "+Thread.currentThread().getState());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
            // 新创建状态(NEW)
            System.out.println(thread0.getName()+":"+thread0.getState());
    
            Thread thread1 = new Thread(() -> {
                try {
                    System.out.println("thread1 进入:计时等待状态(TIMED_WAITING)");
                    Thread.sleep(2);
                    System.out.println("thread1 出来:计时等待状态(TIMED_WAITING)");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 被阻塞状态(BLOCKED)
                synchronized (object){
                    System.out.println("thread1 解除:等待唤醒状态(WAITING)");
                    object.notify();
                    System.out.println("thread1 解除完成:等待唤醒状态(WAITING)");
                }
                System.out.println("thread1 "+Thread.currentThread().getState());
            });
            // 新创建状态(NEW)
            System.out.println(thread1.getName()+":"+thread1.getState());
    
            printState(thread0);
            printState(thread1);
    
            // 可运行状态(RUNNABLE)
            thread0.start();
            // 可运行状态(RUNNABLE)
            thread1.start();
    
        }
        
        
        // 使用独立线程来打印线程状态
        private static void printState(Thread thread) {
            new Thread(()->{
                while (true){
                    System.out.println(thread.getName()+":"+thread.getState());
                    if (thread.getState().equals(Thread.State.TERMINATED)){
                        System.out.println(thread.getName()+":"+thread.getState());
                        break;
                    }
                }
            }).start();
        }
    }

    执行结果:简化后的输出结果

    Thread-0:NEW
    Thread-1:NEW
    Thread-0:RUNNABLE
    Thread-1:RUNNABLE
    thread0 进入:等待唤醒状态(WAITING)
    Thread-1:BLOCKED
    thread1 进入:计时等待状态(TIMED_WAITING)
    Thread-0:BLOCKED
    Thread-0:WAITING
    ……
    Thread-0:WAITING
    Thread-1:BLOCKED
    Thread-1:TIMED_WAITING
    ……
    Thread-1:TIMED_WAITING
    Thread-1:BLOCKED
    ……
    Thread-1:BLOCKED
    Thread-0:WAITING
    ……
    Thread-0:WAITING
    thread1 出来:计时等待状态(TIMED_WAITING)
    Thread-0:WAITING
    Thread-1:BLOCKED
    thread1 解除:等待唤醒状态(WAITING)
    Thread-1:BLOCKED
    Thread-0:WAITING
    Thread-0:BLOCKED
    thread1 解除完成:等待唤醒状态(WAITING)
    Thread-1:BLOCKED
    thread1 RUNNABLE
    Thread-0:BLOCKED
    Thread-1:TERMINATED
    thread0 被解除完成:等待唤醒状态(WAITING)
    Thread-0:BLOCKED
    thread0 RUNNABLE
    Thread-0:TERMINATED

    What are the 6 states and life cycles of Java threads?

    最终的执行结果如图。

    注意:因为案例中使用了独立线程来打印不同线程的状态,会出现状态打印稍微延迟的情况。

    The above is the detailed content of What are the 6 states and life cycles of Java threads?. For more information, please follow other related articles on the PHP Chinese website!

    Statement:
    This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete