刚开始接触java时,就觉得多线程是一个障碍,不容易理解,当时选择了跳过,不过工作一段时间后,发现这块还是需要深入研究一下的,及时平时工作中不使用多线程,但一定会使用web容器,比如tomcat,也是会接触到多喜爱能成,况且现在工作中也是需要使用到多线程。首先从简单的开始,了解线程的状态,查看Thread源码,与getState方法在一起的有个枚举State,其包含了线程的所有状态

 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;
    }

通过以上代码了解到,线程有六种状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING、TERMINATED

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

根据个人理解,简单列出了各状态之间的转换

java中线程状态 随笔 第1张

 

NEW到RUNNABLE状态不可回退

RUNNABLE到TERMINATED状态不可回退

代码验证NEW,RUNNABLE和TERMINATED状态

package com.demo;

public class ThreadTest {

    public static void main(String[] args) {
        Thread t = new Thread() {

            @Override
            public void run() {
                System.out.println("run");
            }
        };

        System.out.println(t.getState()); // NEW,还未调用start方法
        t.start();
        System.out.println(t.getState()); // RUNNABLE,调用了start方法,但线程还未结束

        try {
            // 等待线程结束,其实休眠毫秒级应该就可以结束
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(t.getState());// TERMINATED,线程结束

    }
}

输出结果

java中线程状态 随笔 第2张

 

 验证BLOCK与WAITING状态

package com.demo;

public class ThreadTest {

    public static void main(String[] args) {

        Runnable r = new Runnable() {

            @Override
            public void run() {
                synchronized (this) {
                    try {
                        Thread.sleep(50000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        };

        Thread t1 = new Thread(r, "Thread1");
        Thread t2 = new Thread(r, "Thread2");
        
        // 优先级数字范围为1到10,默认5,数字越小,优先级越高
        t1.setPriority(5);
        t2.setPriority(8);

        t1.start();
        t2.start();

    }
}

打包成jar包,java -cp thread.jar com.demo.ThreadTest

ps找到对应的pid

java中线程状态 随笔 第3张

Thread1优先执行,获取到锁,调用了sleep方法,处于TIMED_WAITING状态,Thread2未获取到锁,处于BLOCKED状态

将上述测试中Thread.sleep方法改为this.wait()

 java中线程状态 随笔 第4张

jstack查看结果

java中线程状态 随笔 第5张

 调用wait方法释放了锁,所以两条线程依次进入到synchronized代码块,处于WAITING状态,只有等到被notify或者notifyAll才能恢复为RUNNABLE状态,而有参的sleep或者wait等方法,则可以在制定的时间过后,自动变为RUNNABLE状态。

向this.wait方法传递参数

java中线程状态 随笔 第6张

 

java中线程状态 随笔 第7张

 两条线程均处于TIMED_WAITING状态,说明它们同样都获取到了锁,wait方法,无论是否带参数,都会释放锁,但sleep不会释放锁

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄