简介

  • Java程序运行中的可以执行的一些操作和方法
  • 直接看源码有哪些功能即可

    Runtime代码

    1. public class Runtime {
    2. // 单例设置模式 懒汉式
    3. private static Runtime currentRuntime = new Runtime();
    4. public static Runtime getRuntime() {
    5. return currentRuntime;
    6. }
    7. private Runtime() {}
    8. // 从System获得系统安全管理器
    9. public void exit(int status) {
    10. SecurityManager security = System.getSecurityManager();
    11. if (security != null) {
    12. security.checkExit(status);
    13. }
    14. // 执行Shutdown的静态方法 status是延迟时间
    15. Shutdown.exit(status);
    16. }
    17. // 调用 ApplicationShutdownHooks 的钩子方法 注册新的虚拟机关闭挂钩
    18. public void addShutdownHook(Thread hook) {
    19. SecurityManager sm = System.getSecurityManager();
    20. if (sm != null) {
    21. sm.checkPermission(new RuntimePermission("shutdownHooks"));
    22. }
    23. ApplicationShutdownHooks.add(hook);
    24. }
    25. // 取消注册某个先前已注册的虚拟机关闭挂钩
    26. public boolean removeShutdownHook(Thread hook) {
    27. SecurityManager sm = System.getSecurityManager();
    28. if (sm != null) {
    29. sm.checkPermission(new RuntimePermission("shutdownHooks"));
    30. }
    31. return ApplicationShutdownHooks.remove(hook);
    32. }
    33. // 调用 Shutdown的halt 方法
    34. // 强行终止目前正在运行的Java虚拟机。 此方法从不正常返回
    35. public void halt(int status) {
    36. SecurityManager sm = System.getSecurityManager();
    37. if (sm != null) {
    38. sm.checkExit(status);
    39. }
    40. Shutdown.halt(status);
    41. }
    42. // 启用或禁用退出终结
    43. @Deprecated
    44. public static void runFinalizersOnExit(boolean value) {
    45. SecurityManager security = System.getSecurityManager();
    46. if (security != null) {
    47. try {
    48. security.checkExit(0);
    49. } catch (SecurityException e) {
    50. throw new SecurityException("runFinalizersOnExit");
    51. }
    52. }
    53. Shutdown.setRunFinalizersOnExit(value);
    54. }
    55. public Process exec(String command) throws IOException {
    56. return exec(command, null, null);
    57. }
    58. public Process exec(String command, String[] envp) throws IOException {
    59. return exec(command, envp, null);
    60. }
    61. public Process exec(String command, String[] envp, File dir)
    62. throws IOException {
    63. if (command.length() == 0)
    64. throw new IllegalArgumentException("Empty command");
    65. StringTokenizer st = new StringTokenizer(command);
    66. String[] cmdarray = new String[st.countTokens()];
    67. for (int i = 0; st.hasMoreTokens(); i++)
    68. cmdarray[i] = st.nextToken();
    69. return exec(cmdarray, envp, dir);
    70. }
    71. public Process exec(String cmdarray[]) throws IOException {
    72. return exec(cmdarray, null, null);
    73. }
    74. public Process exec(String[] cmdarray, String[] envp) throws IOException {
    75. return exec(cmdarray, envp, null);
    76. }
    77. public Process exec(String[] cmdarray, String[] envp, File dir)
    78. throws IOException {
    79. return new ProcessBuilder(cmdarray)
    80. .environment(envp)
    81. .directory(dir)
    82. .start();
    83. }
    84. // 本地方法 返回提供给Java虚拟机的处理器数量 也就是核心数量
    85. public native int availableProcessors();
    86. // 返回的空闲内存在Java虚拟机的数量。 调用gc方法可能会导致增加返回的值freeMemory.
    87. public native long freeMemory();
    88. // 返回的总共的内存在Java虚拟机的数量。
    89. public native long totalMemory();
    90. // 返回最大的内存
    91. public native long maxMemory();
    92. // 主动GC 但是不一定执行
    93. public native void gc();
    94. private static native void runFinalization0();
    95. public void runFinalization() {
    96. runFinalization0();
    97. }
    98. public native void traceInstructions(boolean on);
    99. public native void traceMethodCalls(boolean on);
    100. // 通过加载的文件名参数指定的本地库。 文件名参数必须是绝对路径名。
    101. @CallerSensitive
    102. public void load(String filename) {
    103. load0(Reflection.getCallerClass(), filename);
    104. }
    105. synchronized void load0(Class<?> fromClass, String filename) {
    106. SecurityManager security = System.getSecurityManager();
    107. if (security != null) {
    108. security.checkLink(filename);
    109. }
    110. if (!(new File(filename).isAbsolute())) {
    111. throw new UnsatisfiedLinkError(
    112. "Expecting an absolute path of the library: " + filename);
    113. }
    114. ClassLoader.loadLibrary(fromClass, filename, true);
    115. }
    116. // 加载由指定的本地库libname说法。
    117. // 该libname参数必须不包含任何特定于平台的前缀,文件扩展名或路径
    118. // 如果所谓的本地库libname静态与虚拟机相连,则JNI_OnLoad_ libname由库导出函数被调用
    119. @CallerSensitive
    120. public void loadLibrary(String libname) {
    121. loadLibrary0(Reflection.getCallerClass(), libname);
    122. }
    123. synchronized void loadLibrary0(Class<?> fromClass, String libname) {
    124. SecurityManager security = System.getSecurityManager();
    125. if (security != null) {
    126. security.checkLink(libname);
    127. }
    128. if (libname.indexOf((int)File.separatorChar) != -1) {
    129. throw new UnsatisfiedLinkError(
    130. "Directory separator should not appear in library name: " + libname);
    131. }
    132. ClassLoader.loadLibrary(fromClass, libname, false);
    133. }
    134. // 获取本地的输入流 已经被弃用
    135. @Deprecated
    136. public InputStream getLocalizedInputStream(InputStream in) {
    137. return in;
    138. }
    139. // 获取输出流 已经被启用
    140. @Deprecated
    141. public OutputStream getLocalizedOutputStream(OutputStream out) {
    142. return out;
    143. }
    144. }

    Shutdown

    class Shutdown {
    
      // 终止得状态码
      // 正在运行
      private static final int RUNNING = 0;
      // 处于挂钩态
      private static final int HOOKS = 1;
      private static final int FINALIZERS = 2;
      // 默认就是 运行态
      private static int state = RUNNING;
    
      // 应该在退出时运行所有终结器 默认为false
      private static boolean runFinalizersOnExit = false;
    
      //系统关闭挂钩已在预定义的插槽中注册
      // 最大得 钩子数量
      private static final int MAX_SYSTEM_HOOKS = 10;
      // 挂钩线程数组
      private static final Runnable[] hooks = new Runnable[MAX_SYSTEM_HOOKS];
    
      // 当前正在运行的关闭挂钩的索引钩阵列
      private static int currentRunningHook = 0;
    
      // 前面的静态字段受此锁保护
      private static class Lock { };
      private static Object lock = new Lock();
    
      // 停止锁
      private static Object haltLock = new Lock();
      static void setRunFinalizersOnExit(boolean run) {
          synchronized (lock) {
              runFinalizersOnExit = run;
          }
      }
    
      // 添加一个新的关闭挂钩
      static void add(int slot, boolean registerShutdownInProgress, Runnable hook) {
          synchronized (lock) {
              if (hooks[slot] != null)
                  throw new InternalError("Shutdown hook at slot " + slot + " already registered");
    
              if (!registerShutdownInProgress) {
                  if (state > RUNNING)
                      throw new IllegalStateException("Shutdown in progress");
              } else {
                  if (state > HOOKS || (state == HOOKS && slot <= currentRunningHook))
                      throw new IllegalStateException("Shutdown in progress");
              }
    
              hooks[slot] = hook;
          }
      }
    
      // 运行挂钩线程
      private static void runHooks() {
          for (int i=0; i < MAX_SYSTEM_HOOKS; i++) {
              try {
                  Runnable hook;
                  synchronized (lock) {
                      // acquire the lock to make sure the hook registered during
                      // shutdown is visible here.
                      currentRunningHook = i;
                      hook = hooks[i];
                  }
                  if (hook != null) hook.run();
              } catch(Throwable t) {
                  if (t instanceof ThreadDeath) {
                      ThreadDeath td = (ThreadDeath)t;
                      throw td;
                  }
              }
          }
      }
      // 停止的方法
      static void halt(int status) {
          synchronized (haltLock) {
              halt0(status);
          }
      }
    
      // 本地方法中止延时
      static native void halt0(int status);
    
      // 调用所有的的终结
      private static native void runAllFinalizers();
    
      // 实际的关机方法
      // 实际的关机顺序在此定义
      private static void sequence() {
          synchronized (lock) {
              if (state != HOOKS) return;
          }
          runHooks();
          boolean rfoe;
          synchronized (lock) {
              state = FINALIZERS;
              rfoe = runFinalizersOnExit;
          }
          if (rfoe) runAllFinalizers();
      }
    
      // 终止当前方法的 exit 方法
      static void exit(int status) {
          boolean runMoreFinalizers = false;
          synchronized (lock) {
              if (status != 0) runFinalizersOnExit = false;
              switch (state) {
                  case RUNNING:       /* Initiate shutdown */
                      state = HOOKS;
                      break;
                  case HOOKS:         /* Stall and halt */
                      break;
                  case FINALIZERS:
                      if (status != 0) {
                          halt(status);
                      } else {
                          runMoreFinalizers = runFinalizersOnExit;
                      }
                      break;
              }
          }
          if (runMoreFinalizers) {
              runAllFinalizers();
              halt(status);
          }
          synchronized (Shutdown.class) {
              sequence();
              halt(status);
          }
      }
    
      // 终止的方法
      static void shutdown() {
          synchronized (lock) {
              // 检查状态
              switch (state) {
                  case RUNNING:       /* Initiate shutdown */
                      state = HOOKS;
                      break;
                  case HOOKS:         /* Stall and then return */
                  case FINALIZERS:
                      break;
              }
          }
          // 加锁调用
          synchronized (Shutdown.class) {
              sequence();
          }
      }
    }
    

    ApplicationShutdownHooks

    ```java // 这是一个 用于跟踪和运行通过注册的用户级别关闭挂钩的类 class ApplicationShutdownHooks {

    // 套勾集合 private static IdentityHashMap hooks; static {

      try {
          Shutdown.add(1 /* shutdown hook invocation order */,
                       false /* not registered if shutdown in progress */,
                       new Runnable() {
                           public void run() {
                               runHooks();
                           }
                       }
                      );
          hooks = new IdentityHashMap<>();
      } catch (IllegalStateException e) {
          hooks = null;
      }
    

    }

private ApplicationShutdownHooks() {}

// 添加一个新的关闭挂钩。检查关闭状态和钩子本身,但不进行任何安全性检查
static synchronized void add(Thread hook) {
    if(hooks == null)
        throw new IllegalStateException("Shutdown in progress");

    if (hook.isAlive())
        throw new IllegalArgumentException("Hook already running");

    if (hooks.containsKey(hook))
        throw new IllegalArgumentException("Hook previously registered");

    hooks.put(hook, hook);
}

// 删除以前注册的钩子。与add方法一样,此方法不会进行任何安全检查
static synchronized boolean remove(Thread hook) {
    if(hooks == null)
        throw new IllegalStateException("Shutdown in progress");

    if (hook == null)
        throw new NullPointerException();

    return hooks.remove(hook) != null;
}

// 遍历所有应用程序挂钩,为每个要运行的创建一个新线程。挂钩同时运行,并且此方法等待完成
static void runHooks() {
    Collection<Thread> threads;
    synchronized(ApplicationShutdownHooks.class) {
        threads = hooks.keySet();
        hooks = null;
    }

    for (Thread hook : threads) {
        hook.start();
    }
    for (Thread hook : threads) {
        try {
            hook.join();
        } catch (InterruptedException x) { }
    }
}

} ```

总结

  • 实际上 Runtime通过调用另外的2个类中的方法来实现自己的一些方法
  • 通过Runtime可以 快速的得到系统的一些数据
  • 而其中的方法 availableProcessors() 可以用来获取系统的核心数 在多线程中设置线程池的大小用的到
  • 其中的退出方法,其实是调用底层的JVM本地方法的退出方法就是调用 Shutdown的halt() 方法,而halt()方法调用halt0()本地方法
  • 同时也可以加载一些包等