栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【JUC】线程状态及各状态下与锁和CPU的关系

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【JUC】线程状态及各状态下与锁和CPU的关系

线程的状态

Thread.State枚举类型中定义了线程的6种状态:NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING和TERMINATED。

线程在某一时刻只能拥有一种状态,但是在线程的整个生命周期,线程的状态会发生变化。

各状态的说明

NEW:线程已经被创建,但还没调用start()。此时的线程是不可运行的,CPU将不会为其分配时间;

RUNNABLE:当新创建的线程调用了start(),线程便进入了RUNNABLE状态。RUNNABLE状态是指可以获得CPU运行时间的状态,如果线程在此状态下,线程有两种子状态,一种是等待CPU时间,另一种是获得了CPU时间在执行代码。

BLOCKED:线程无法获取对象锁时的状态。当线程试图获取某个锁,而锁被其他线程持有,则该线程进入BLOCKED状态。此状态下线程会阻塞,当线程成功获取到锁,线程将切换为RUNNABLE状态。BLOCKED状态无法获得CPU运行时间。

WAITING(无限等待):线程在执行过程中,主动出让自己CPU运行时间,让其他线程先执行,自己等待其它线程的特定操作后再恢复执行。WAITING状态的线程不能自动唤醒的,必须等待另外的线程调用notify()或notifyAll()方法才能够唤醒。

TIMED_WAITING(计时等待):与WAITING状态相似,TIMED_WAITING增加了时间限制,其实没有外部信号,在等待时间超时后,线程自动恢复。

TERMINATED:线程的终止态,当线程执行完自己的任务,或在执行任务中发生了异常,线程都会进入TERMINATED,表示线程已经到了生命周期的末尾。

下图是关于线程间各状态切换的过程及发生状态切换的一些条件。

【java面试】探究Java线程状态及转换

以下是一些测试代码,可以运行下清晰的了解到状态。
各状态切换测试:

public class ThreadStateTest {

    public static void main(String[] args){
        // 没调用start方法查看下thread状态 NEW
        threadStateNew();
        // 调用start方法查看thread状态 RUNNABLE
        workingThread();
        // thread调用join方法查看状态 TERMINATED
        threadStateTerminate();
        // main线程持有锁(可重入锁)的同时查看thread状态 WAITING
        threadBlockedByLock();
        // 多个线程同时竞争同一把锁时,未获得锁的线程处于 BLOCKED
        threadBlockedBySynchronized();

        threadSleep();

        threadWait();

        threadTimeWait();
    }

    private static void threadStateNew(){
        System.out.println("--------------------------");
        System.out.print("Never Start Thread State:");
        Thread thread = new Thread(()->{

        }, "Thread Never Start");
        //print NEW
        System.out.println(thread.getState());
        System.out.println("--------------------------");
    }

    private static void workingThread(){
        System.out.println("--------------------------");
        Thread thread = new Thread(()->{
           for(int i=0; i<100; i++){
               doSomeElse();
           }
        });

        thread.start();

        doSomeElse();
        //print RUNNABLE
        System.out.println("Working Thread State:" + thread.getState());
        System.out.println("--------------------------");
    }

    private static void threadStateTerminate(){
        System.out.println("--------------------------");
        System.out.print("Finish Job Thread State:");
        Thread thread = new Thread(()->{

        }, "Thread Finish Job");
        thread.start();


        try {
            //Main Thread Will Wait util this thread finished job
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //print TERMINATED
        System.out.println(thread.getState());
        System.out.println("--------------------------");
    }

    
    private static void threadBlockedByLock(){
        System.out.println("--------------------------------------");
        System.out.println("Thread State Blocked By Lock:");
        ReentrantLock lock = new ReentrantLock();
        Thread thread = new Thread(lock::lock, "Blocked Thread");
        lock.lock();
        try {
            thread.start();
            doSomeElse();
            //print WAITING
            System.out.println(thread.getState());
        } catch (Exception e){
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        System.out.println("--------------------------------------");

    }

    
    private static void threadBlockedBySynchronized(){
        System.out.println("--------------------------------------");
        System.out.println("Thread Blocked By Synchronized:");
        Thread thread = new Thread(() -> {
            synchronized (ThreadStateTest.class){
                System.out.println("thread成功获取synchronized锁");
            }
        }, "Blocked by Synchronized Thread");
        thread.start();
        synchronized (ThreadStateTest.class){
            System.out.println("main成功获取synchronized锁");
            doSomeElse();
            // print BLOCKED 怎么还能打印RUNNABLE???
            // 阻塞main线程3s,等待thread去获取锁
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Thread State is:" + thread.getState());
            System.out.println("锁释放...");
        }
        System.out.println("--------------------------------------");
    }

    private static void threadSleep(){
        System.out.println("--------------------------");
        System.out.print("Sleeping Thread:");
        Thread thread = new Thread(()->{
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "Thread sleep");

        thread.start();
        doSomeElse();
        //print TIMED_WAITING
        System.out.println(thread.getState());
        System.out.println("--------------------------");
    }


    private static void threadWait(){
        System.out.println("--------------------------");
        System.out.print("Thread Waiting:");
        Object lock = new Object();
        Thread threadA = new Thread(()->{
            synchronized (lock){
                try {
                    lock.wait();

                    for(int i=0; i<100; i++){
                        doSomeElse();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }, "Thread Waiting");

        Thread threadB = new Thread(()->{
            synchronized (lock){
                //print WAITING
                System.out.println("Before Notify, Thread A State:" + threadA.getState());
                lock.notify();
                //print BLOCKED
                System.out.println("After Notify, Thread A State:" + threadA.getState());
            }
        });


        threadA.start();
        doSomeElse();
        threadB.start();

        try {
            threadB.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //print RUNNABLE
        System.out.println("After Thread B finish job, Thread A State:" + threadA.getState());
        System.out.println("--------------------------");
    }

    private static void threadTimedWait(){
        System.out.println("--------------------------");
        System.out.print("Thread Waiting:");
        Object lock = new Object();
        Thread threadA = new Thread(()->{
            synchronized (lock){
                try {
                    lock.wait(1000);

                    for(int i=0; i<100; i++){
                        doSomeElse();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }, "Thread Waiting");

        Thread threadB = new Thread(()->{
            synchronized (lock){
                //print TIMED_WAITING
                System.out.println("Before Notify, Thread A State:" + threadA.getState());
                lock.notify();
                //print BLOCKED
                System.out.println("After Notify, Thread A State:" + threadA.getState());
            }
        });


        threadA.start();
        doSomeElse();
        threadB.start();

        try {
            threadB.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //print RUNNABLE
        System.out.println("After Thread B finish job, Thread A State:" + threadA.getState());
        System.out.println("--------------------------");
    }
    
    private static void doSomeElse(){
        double meanless = 0d;
        for(int i=0; i<10000; i++){
            meanless += Math.random();
        }
    }

}

CPU时间运行测试:

public class ThreadCPUTimeTest {

    public static void main(String[] args) {
        testBlockedThreadCPUTime();
    }

    protected static void testBlockedThreadCPUTime() {
        Object lock = new Object();

        Thread threadA = new Thread(() -> {
            synchronized (lock) {
                doSomethingElse();
            }
        }, "ThreadA: Blocked because of synchronized");

        Thread threadB = new Thread(() -> {
            synchronized (lock) {
                try {
                    threadA.start();
                    Thread.sleep(100000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "ThreadB: With Monitor But Sleep");

        threadB.start();
        //Main Thread Executing Job
        for (int i = 0; i < 100000; i++) {
            doSomethingElse();
        }
    }

    private static void doSomethingElse() {
        double meanless = 0d;

        for (int i = 0; i < 10000; i++) {
            meanless += Math.random();
        }
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/684392.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号