Java多线程之线程状态

threadStatus线程状态

    private volatile int threadStatus;

线程状态一般有以下值

    public enum State {
        NEW,

        RUNNABLE,

        BLOCKED,

        WAITING,

        TIMED_WAITING,

        TERMINATED;
    }

状态图

在这里插入图片描述

源码解析及例子

BLOCKED
源码解析
    public enum State {
        // other source codes...

        /**
         * 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状态,它正在等待获得一个监视器锁为了能够
         1. 进入一个synchronized修饰的代码块或者方法
         2. 在调用Object.wait()方法后重新进入synchronized修饰的代码块或者方法
         */
        BLOCKED,

        // other source codes...
    }
第一次enter例子

先看例子的流程图
在这里插入图片描述

代码实现

public class Enter {

    public static void main(String[] args) throws InterruptedException {
        
        // 创建计算器实例
        Counter counter = new Counter();
        
        // 开启线程1
        Thread thread1 = new Thread("线程1") {
            @Override
            public void run() {
                counter.increase();
            }
        };
        thread1.start();
        Thread.sleep(100); // 确保thread1得到执行
        
        // 开启线程2
        Thread thread2 = new Thread("线程2") {
            @Override
            public void run() {
                counter.increase();
            }
        };
        thread2.start();
        Thread.sleep(100); // 确保thread2得到执行
        
        System.out.println("State of thread2: " + thread2.getState());
    }
}

// 创建计算器类
class Counter{
    private int count = 0;
    
    public synchronized void increase() {
        System.out.println(Thread.currentThread().getName() + " starts counting!!!");
        try {
            count++;
            Thread.sleep(1000); // 线程1执行后阻塞,使得线程2可以进入BLOCKED状态
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " ends counting!!!");
    }
}

执行代码后结果

线程1 starts counting!!!
State of thread2: BLOCKED
线程1 ends counting!!!
线程2 starts counting!!!
线程2 ends counting!!!

在线程1结束之前线程2被阻塞,状态为BLOCKED

reenter例子

例子的流程图

在这里插入图片描述

代码实现

public class Reenter {
    public static void main(String[] args) throws InterruptedException {
        // 创建Account实例
        Account account = new Account();
        
        // 开启取钱线程
        Thread thread1 = new Thread("取钱线程") {
            @Override
            public void run() {
                account.take(50);
            }
        };
        thread1.start();
        Thread.sleep(100); // 确保取钱线程得到执行
        System.out.println("State of " + thread1.getName() + ": " + thread1.getState());
        
        // 开启存钱线程
        Thread thread2 = new Thread("存钱线程") {
            @Override
            public void run() {
                account.store(100);
            }
        };
        thread2.start();
        Thread.sleep(100); // 确保存钱线程得到执行
        
        System.out.println("State of " + thread1.getName() + ": " + thread1.getState());
    }
}
// 定义账户类,该类有money变量记录当前有多少钱; store方法表示存钱;take方法表示取钱
class Account{
    private int money = 0;
    
    // 存钱
    public synchronized void store(int storeCash) {
        System.out.println(Thread.currentThread().getName() + "-存钱 starts!!!");
        money += storeCash;
        notify();
        try {
            Thread.sleep(1000); // 通知后暂时不退出,使取钱线程进入blocked状态
        } catch (Exception e) {
        }
        System.out.println(Thread.currentThread().getName() + "-存钱 ends!!!");
    }
    
    // 取钱
    public synchronized void take(int takeCash) {
        System.out.println(Thread.currentThread().getName() + "-取钱 starts!!!");
        // 钱不够的时候阻塞
        while (takeCash > money) {
            try {
                wait();
            } catch (Exception e) {
            }
        }
        money -=takeCash;
        System.out.println(Thread.currentThread().getName() + "-取钱 ends!!!");
    }
}

运行后结果

取钱线程-取钱 starts!!!
State of 取钱线程: WAITING
存钱线程-存钱 starts!!!
State of 取钱线程: BLOCKED
存钱线程-存钱 ends!!!
取钱线程-取钱 ends!!!
WAITING
源码解析
public enum State {
        // other source codes...

        /**
         * 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>
         * 当调用了下面其中一个方法后,线程会进入WAITING状态
         * 1. Object.wait()不带参数
           2. Thread.join()不带参数
           3. LockSupport.park()
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
           处于WAITING状态的线程在等待另一个线程执行某些特殊操作后才能改变状态
         *
         * For example, a thread that has called {@code Object.wait()}
         * on an object is waiting for another thread to call
         * {@code Object.notify()} or {@code Object.notifyAll()} on
         * that object. A thread that has called {@code Thread.join()}
         * is waiting for a specified thread to terminate.
           比如说
           1. 如果调用了Object.wait(),需要另一个线程调用Object.notify()或者Object.notifyAll()
           2. 如果调用了Thread.join(),需要另一个线程终止才能退出该状态
         */
        WAITING,

        // other source codes...
    }

例子解析

wait
public class Wait {

    public static void main(String[] args) throws InterruptedException {
        
        // 创建等待类实例
        WaitClazz waitClazz = new WaitClazz();
        
        // 创建等待线程1
        Thread thread1 = new Thread("thread-1") {
            @Override
            public void run() {
                waitClazz.waitTest();
            }
        };
        thread1.start();
        Thread.sleep(100); // 确保线程1执行
        System.out.println("State of " + thread1.getName() + " is " + thread1.getState());
        
        // 唤醒单个等待线程
        Thread thread2 = new Thread("thread-2") {
            @Override
            public void run() {
                waitClazz.notifyTest();
            }
        };
        thread2.start();
        Thread.sleep(100); // 确保线程2执行
        System.out.println("State of " + thread1.getName() + " is " + thread1.getState());
        Thread.sleep(5000);
        
        System.out.println("-------------------------------------");
        
        // 创建等待线程3
        Thread thread3 = new Thread("thread-3") {
            @Override
            public void run() {
                waitClazz.waitTest();
            }
        };
        thread3.start();
        Thread.sleep(100); // 确保线程3执行
        System.out.println("State of " + thread3.getName() + " is " + thread3.getState());
        
        // 创建等待线程4
        Thread thread4 = new Thread("thread-4") {
            @Override
            public void run() {
                waitClazz.waitTest();
            }
        };
        thread4.start();
        Thread.sleep(100); // 确保线程4执行
        System.out.println("State of " + thread4.getName() + " is " + thread4.getState());
        
        // 唤醒所有线程
        Thread thread5 = new Thread("thread-5") {
            @Override
            public void run() {
                waitClazz.notifyAllTest();
            }
        };
        thread5.start();
        Thread.sleep(100); // 确保线程5执行
        System.out.println("State of " + thread3.getName() + " is " + thread3.getState());
        System.out.println("State of " + thread4.getName() + " is " + thread4.getState());
    }
}
// 创建等待类
class WaitClazz {
    // 等待
    public synchronized void waitTest() {
        try {
            wait();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    
    // 唤醒单个线程
    public synchronized void notifyTest() {
        notify();
        System.out.println(Thread.currentThread().getName() + " notify.");
    }
    
    // 唤醒所有线程
    public synchronized void notifyAllTest() {
        notifyAll();
        System.out.println(Thread.currentThread().getName() + " notifyAll.");
    }
}

运行后结果

State of thread-1 is WAITING
thread-2 notify.
State of thread-1 is TERMINATED
-------------------------------------
State of thread-3 is WAITING
State of thread-4 is WAITING
thread-5 notifyAll.
State of thread-3 is TERMINATED
State of thread-4 is TERMINATED
join
    public static void main(String[] args) throws InterruptedException {
        Thread parent = Thread.currentThread();
        Thread subThread = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 500000; i++) {
                }
                System.out.println("Inner->Main线程状态: " + parent.getState());
                System.out.println("子线程结束");
            }
        };
        
        subThread.start();
        subThread.join();
        System.out.println("Outer->Main线程状态: " + parent.getState());
    }

结果

Inner->Main线程状态: WAITING
子线程结束
Outer->Main线程状态: RUNNABLE

当subThread调用join方法后会阻塞Main线程,直到它自己执行完毕才会继续往下走。为了更清楚了解我们看下在没有调用join方法下的结果

    public static void main(String[] args) throws InterruptedException {
        Thread parent = Thread.currentThread();
        Thread subThread = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 500000; i++) {
                }
                System.out.println("Inner->Main线程状态: " + parent.getState());
                System.out.println("子线程结束");
            }
        };
        
        subThread.start();
//        subThread.join();
        System.out.println("Outer->Main线程状态: " + parent.getState());
    }

结果

Outer->Main线程状态: RUNNABLE
Inner->Main线程状态: TERMINATED
子线程结束

子线程不阻塞Main线程,在执行子线程run时主线程已经终止了

park
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            System.out.println("State before park: " + Thread.currentThread().getState());
            LockSupport.park();
        });
        thread.start();
        Thread.sleep(1000);
        
        System.out.println("State before unpark: " + thread.getState());
        LockSupport.unpark(thread);
    }

结果

State before park: RUNNABLE
State before unpark: WAITING
TIMED_WAITING
源码解析
    public enum State {
        // other source codes...

        /**
         * 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,

        // other source codes...
    }
sleep
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
            try {
                Thread.sleep(1000);
                System.out.println("State after sleep: " + Thread.currentThread().getState());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println("State after created: " + thread.getState());
        thread.start();
        System.out.println("State after start: " + thread.getState());
        Thread.sleep(500); // 确保线程进入休眠状态
        System.out.println("State when sleeping: " + thread.getState());
        Thread.sleep(5000); // 确保线程退出
        System.out.println("State after executed: " + thread.getState());
    }

结果

State after created: NEW
State after start: RUNNABLE
State when sleeping: TIMED_WAITING
State after sleep: RUNNABLE
State after executed: TERMINATED
wait
    public static void main(String[] args) throws InterruptedException {
        class WaitClazz {
            public synchronized void waitTest(long millSeconds) throws InterruptedException {
                wait(1000);
            }
        }
        WaitClazz waitClazz = new WaitClazz();
        Thread thread = new Thread(() -> {
            try {
                waitClazz.waitTest(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        
        System.out.println("State after created: " + thread.getState());
        thread.start();
        System.out.println("State after start: " + thread.getState());
        Thread.sleep(500); // 确保线程进入等待
        System.out.println("State after sleep: " + thread.getState());
    }

结果

State after created: NEW
State after start: RUNNABLE
State after sleep: TIMED_WAITING
join
    public static void main(String[] args) throws InterruptedException {
        Thread parent = Thread.currentThread();
        Thread subThread = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 50000; i++) {
                }
                System.out.println("Inner->Main线程状态: " + parent.getState());
                System.out.println("线程结束循环");
            }
        };
        
        subThread.start();
        subThread.join(1000);
    }

结果

Inner->Main线程状态: TIMED_WAITING
线程结束循环
parkNanos
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            System.out.println("State before parkNanos: " + Thread.currentThread().getState());
            LockSupport.parkNanos(10 * 1000 * 1000 * 1000);
            System.out.println("State after parkNanos: " + Thread.currentThread().getState());
        });
        thread.start();
        Thread.sleep(500);
        
        System.out.println("State before park timeout: " + thread.getState());
    }

结果

State before parkNanos: RUNNABLE
State before park timeout: TIMED_WAITING
State after parkNanos: RUNNABLE
parkUntil
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            System.out.println("State before parkNanos: " + Thread.currentThread().getState());
            LockSupport.parkUntil(System.currentTimeMillis() + 1000);
            System.out.println("State after parkNanos: " + Thread.currentThread().getState());
        });
        thread.start();
        Thread.sleep(500);
        
        System.out.println("State before park timeout: " + thread.getState());
    }

结果

State before parkNanos: RUNNABLE
State before park timeout: TIMED_WAITING
State after parkNanos: RUNNABLE

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值