zoukankan      html  css  js  c++  java
  • Java源码剖析34讲学习笔记~3

    线程的状态有哪些? 它是如何工作的?

    1. 线程状态

    public enum State {
        /*
         * 新建状态
         * - 线程被创建出来, 但尚未启动时的线程状态
         */
        NEW,
        /*
         * 就绪状态
         * - 表示可以运行的线程状态, 它可能正在运行, 或者是在排队等待操作系统给它分配CPU资源
         */
        RUNNABLE,
        /*
         * 阻塞等待锁的线程状态
         * - 表示处于阻塞状态的线程正在等待监视器锁
         * - 比如等待执行synchronized代码块或者使用synchronized标记的方法
         */
        BLOCKED,
        /*
         * 等待状态
         * - 一个处于等待状态的线程正在等待另一个线程执行某个特定的动作
         * - 比如, 一个线程调用了Object.wait()方法
         * - 那它就在等待另一个线程调用Object.notify()或Object.notifyAll()方法
         */
        WAITING,
        /*
         * 计时等待状态
         * - 和等待状态(WAITING)类似, 它只是多了超时时间
         * - 比如调用了有超时时间设置的方法Object.wait(long timeout)
         *   和 Thread.join(long timeout)等这些方法时它才会进入此状态
         */
        TIMED_WAITING,
        /*
         * 终止状态
         * - 表示线程已经执行完成
         */
        TERMINATED
    }
    

    线程状态

    2. 延伸面试题

    线程一般会作为并发编程的起始问题, 用于引出更多的关于并发编程的面试问题

    • BLOCKED(阻塞等待) 和 WAITING(等待) 有什么区别?

      • BLOCKED 处于活跃状态, 等待其他线程使用完锁资源后继续运行

      • WAITING 处于休眠状态, 需被其他线程唤醒才能继续运行

    • start() 方法和 run() 方法有什么区别?

      • start()

        • 属于Thread自身, 并且使用了synchronized来保证线程安全
        • 可以开启多线程, 让线程从NEW状态转换成RUNNABLE状态
        • 只可调用一次, 否则会抛出 java.lang.IllegalStateException
      • run()

        • 属于Runnable的抽象方法, 必须由调用类重写此方法

        • 只是一个普通的方法

        • 可以多次调用

    • 线程的优先级有什么用? 该如何设置?

      // 线程可以拥有的最小优先级
      public final static int MIN_PRIORITY = 1;
      
      // 线程默认优先级
      public final static int NORM_PRIORITY = 5;
      
      // 线程可以拥有的最大优先级
      public final static int MAX_PRIORITY = 10;
      
      
      // 通过Thread.setPriority()来设置优先级
      public final void setPriority(int newPriority) {
          ThreadGroup g;
          checkAccess();
          // 先验证优先级的合理性
          if(newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
              throw new IllegalArgumentException();
          }
          if((g = getThreadGroup()) != null) {
              // 优先级如果超过线程组的最高优先级, 则把优先级设置为线程组的最高优先级
              if(newPriority > g.getMaxPriority()) {
                  newPriority = g.getMaxPriority();
              }
              setPriority0(priority = newPriority);
          }
      }
      
    • 线程的常用方法有哪些?

      • join()

        public final synchronized void join(long millis) throws InterruptedException {
            long base = System.currentTimeMillis();
            long now = 0;
        	// 超时时间不能小于0
            if (millis < 0) {
                throw new IllegalArgumentException("timeout value is negative");
            }
        	// 等于0表示无限等待, 直到线程执行完为止
            if (millis == 0) {
                // 判断子线程(其他线程)为活跃线程, 则一直等待
                while (isAlive()) {
                    wait(0);
                }
            } else {
                // 循环判断
                while (isAlive()) {
                    long delay = millis - now;
                    if (delay <= 0) {
                        break;
                    }
                    wait(delay);
                    now = System.currentTimeMillis() - base;
                }
            }
        }
        
      • yield()

        // 由 C 或者 C++ 实现的
        /*
         * 给调度程序的提示是当前线程愿意放弃对处理器的当前使用。
         * 调度程序可以随意忽略此提示。
         * Yield是一种启发式尝试,旨在提高线程之间的相对进程,否则将过度利用CPU。
         * 应将其使用与详细的性能分析和基准测试结合起来,以确保它实际上具有所需的效果。
         * 很少适合使用此方法。
         * 它可能对调试或测试有用,因为它可能有助于重现由于竞争条件而产生的错误。
         * 当设计诸如{@link java.util.concurrent.locks}包中的并发控制结构时,它也可能很有用。
         */
        public static native void yield();
        
  • 相关阅读:
    大型门户网站架构设计的可伸缩性
    服务器性能的瓶颈分析
    boost中bind、thread、io_services测试
    C++ 宏定义中字符串连接操作
    完成端口与高性能服务器程序开发
    异步IO、APC、IO完成端口、线程池与高性能服务器
    在模板类中使用字符串作为无类型模板参数
    VS2010 设置全局Include Directories与Library Directories
    Yii的Model ( 模型)创建及使用
    mvc中循环遍历分配的代码
  • 原文地址:https://www.cnblogs.com/unrecognized/p/13264092.html
Copyright © 2011-2022 走看看