zoukankan      html  css  js  c++  java
  • 线程状态及各状态下与锁和CPU的关系

    线程的状态

    Thread.State枚举类型中定义了线程的六种状态:NEWRUNNABLEBLOCKEDWAITINGTIMED_WAITINGTERMINATED

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

    public enum State {
            NEW,
    
            RUNNABLE,
    
            BLOCKED,
    
            WAITING,
    
            TIMED_WAITING,
    
            TERMINATED;
        }
    

    各状态的说明

    NEW

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

    RUNNABLE

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

    BLOCKED

    BLOCKED状态是线程无法获取对象锁时的状态。此状态下线程会阻塞,当线程成功获取到锁,线程将切换为RUNNABLE状态。
    BLOCKED状态无法获得CPU运行时间。

    WAITING

    WAITING状态是指是指线程在执行过程中,主动出让自己CPU运行时间,让其他线程先执行,自己等待其它线程的特定操作后再恢复执行。

    TIMED_WAITING

    TIMED_WAITINGWAITING状态相似,TIMED_WAITING增加了时间限制,其实没有外部信号,在等待时间超时后,线程也会恢复。

    TERMINATED

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

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

    操作 操作前线程状态 操作后线程状态 是否出让CPU时间 是否需要先持有对象锁 是否释放对象锁
    new Thread() NEW
    Thread.start() NEW RUNNABLE
    synchronized能得到对象锁 RUNNABLE RUNNABLE
    synchronized无法得到对象锁 RUNNABLE BLOCKED
    Thread.join() RUNNABLE WAITING
    Thread.join(t) RUNNABLE TIMED_WAITING
    Thread.sleep(t) RUNNABLE TIMED_WAITING
    Object.wait() RUNNABLE WAITING
    Object.wait(t) RUNNABLE TIMED_WAITING
    Object.notify() / Object.notifyAll() RUNNABLE RUNNABLE
    Lock.lock() RUNNABLE WAITING
    Lock.tryLock(t) RUNNABLE TIMED_WAITING
    LockSupport.park() RUNNABLE WAITING
    LockSupport.parkNanos(t)/LockSupport.parkUntil(t) RUNNABLE TIMED_WAITING
    执行结束/执行异常 RUNNABLE TERMINATED

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

    public class ThreadStateTest {
    
        public static void main(String[] args){
            threadStateNew();
    
            workingThread();
    
            threadStateTerminate();
    
            threadBlockedByLock();
    
            threadBlockedBySynchronized();
    
            threadSleep();
    
            threadWait();
    
            threadTimedWait();
        }
    
        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.print("Thread State Blocked By Lock:");
            ReentrantLock lock = new ReentrantLock();
            Thread thread = new Thread(()->{
                    lock.lock();
            }, "Blocked Thread");
    
            lock.lock();
    
            thread.start();
    
            doSomeElse();
            //print WAITING
            System.out.println(thread.getState());
    
            lock.unlock();
            System.out.println("--------------------------");
        }
    
        private static void threadBlockedBySynchronized(){
            System.out.println("--------------------------");
            System.out.print("Thread Blocked By Synchronized:");
            Thread thread = new Thread(()->{
                synchronized (ThreadStateTest.class){
    
                }
            }, "Blocked by Synchronized Thread");
    
            synchronized (ThreadStateTest.class){
                thread.start();
                doSomeElse();
                //print BLOCKED
                System.out.println(thread.getState());
            }
            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("--------------------------");
        }
        /**
         * take some times, let the thread get cpu time
         */
        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();
            }
        }
    }
    

    用VISUALVM可以统计CPU时间:
    CPU运行时间.png

    详细代码可以GitHub

  • 相关阅读:
    如何去掉流氓网站http://www.2345.com/?177
    『ExtJS』01 004. ExtJS 4 确定函数的作用域
    『Java』Servlet 最简教程
    『Java』最简教程
    『ExtJS』01 002. ExtJS 4 类的继承
    『ExtJS』01 003. ExtJS 4 类的混合
    『ExtJS』01 006. ExtJS 4 组件的别名
    『ExtJS』01 007. ExtJS 4 查找组件
    『ExtJS』01 005. ExtJS 4 类的‘Import’
    『ExtJS』01 001. ExtJS 4 类的定义
  • 原文地址:https://www.cnblogs.com/insaneXs/p/12165685.html
Copyright © 2011-2022 走看看