【问题标题】:The best way to keep the main method running保持主要方法运行的最佳方法
【发布时间】:2018-08-31 13:28:26
【问题描述】:

我使用了一种方法来保持 main 方法运行。

public static void main(String[] args) throws InterruptedException {
    while (true) {
        TimeUnit.SECONDS.sleep(1);
    }
}

但我不确定这是不是最好的方法。

谁能给我一些建议?

【问题讨论】:

  • 为什么需要它来保持运行?你还在等什么?
  • 我有一些服务需要main方法加载。
  • 这绝对是最简单的方法,但如果它是一个新软件,您正在编写对事件驱动架构的更改,因此总会有 shaddulers/timers/listeners 等待并保持运行。跨度>
  • @JonSkeet 这是 1 秒,而不是 1 毫秒。
  • @shmosel 当 Jon Skeet 让线程休眠时,它会一直休眠直到 Jon Skeet 准备好唤醒它。

标签: java main


【解决方案1】:

最好的方法是保持 main() 线程不进入 Terminated/Dead 状态。 以下是我经常使用的两种方法-

 public static void main(String[] args) throws InterruptedException {

    System.out.println("Stop me if you can");
   Thread.currentThread().join(); // keep the main running
  }

另一种方法是创建 ReentrantLock 并在其上调用 wait():

public class Test{
private static Lock mainThreadLock = new ReentrantLock();

public static void main(String[] args) throws InterruptedException {

    System.out.println("Stop me if you can");
    synchronized (mainThreadLock) {
        mainThreadLock.wait();
     }
}

【讨论】:

    【解决方案2】:

    你有很多选择,其中一些:

    • 简单线程
    • 定时器任务
    • ScheduledExecutorService

    简单线程:

    public class Task {
      public static void main(String[] args) {
          final long timeInterval = 1000;
          Runnable runnable = new Runnable() {
           public void run() {
              while (true) {
                  System.out.println("Running Task ...");
                    try {
                       Thread.sleep(timeInterval);
                    } catch (InterruptedException e) {
                       e.printStackTrace();
                    }
              }
           }
          };
          Thread thread = new Thread(runnable);
          thread.start();
      }
     }
    

    定时器任务:

     import java.util.Timer;
     import java.util.TimerTask;
     public class Task {
         public static void main(String[] args) {
              TimerTask task = new TimerTask() {
                   @Override
                   public void run() {
                       System.out.println("Running Task ...");
                   }
              };
              Timer timer = new Timer();
              long delay = 0;
              long intevalPeriod = 1000; 
              timer.scheduleAtFixedRate(task, delay,intevalPeriod);
          } 
     }
    

    ScheduledExecutorService:

    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    
    public class Task {
        public static void main(String[] args) {
            Runnable runnable = new Runnable() {
                 public void run() {
                   System.out.println("Running Task ...");
                 }
            };
        ScheduledExecutorService service = Executors
                    .newSingleThreadScheduledExecutor();
        service.scheduleAtFixedRate(runnable, 0, 1, TimeUnit.SECONDS);
        }
     }
    

    【讨论】:

      【解决方案3】:

      您应该使用 ExecutorService 并提交一个等待读取服务输出的任务。

      package demo;
      
      import java.util.concurrent.Executors;
      import java.util.concurrent.ExecutorService;
      
      public class TaskDemo {
          public static void main(String[] args ) {
              System.out.println("Hello");
      
              ExecutorService threadPool = Executors.newFixedThreadPool(1);
      
              Runnable task = () -> {
                  try {
                      //Loop to read your services's output
                      Thread.sleep(1000);
                      System.out.println("This is from Task");
                  } catch(InterruptedException e) {
                      e.printStackTrace();
                  }
              };
              threadPool.execute(task);
              //Wait for the task to finish and shutdow the pool
              threadPool.shutdown();
          }
      }
      

      【讨论】:

      • @Frank.Dai:这样,main 方法会一直运行到任务完成,所以只要你想保持任务运行就行。
      • 你需要这样一个新线程,我认为这不是最好的方法。
      • @Frank.Dai:我认为如果我们想等待某些东西,最好的方法是使用线程,因为它不会阻塞我们的主线程来执行其他任务。当等待线程完成其任务时,它会向主线程发送一个信号。
      【解决方案4】:

      这是一种维护主要 java 实例运行直到您想要退出的方法。使用 GUI 来做到这一点:

      public static void main(String[] args){
          JFrame jFrame = new JFrame();
          jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          jFrame.setLocationRelativeTo(null);
          jFrame.setSize(480, 260);
          jFrame.setVisible(true);
          //do some task here
      }
      

      【讨论】:

      • @Fildor 他想保持主运行,我认为可以
      • 当然,只是说。此解决方案的副作用是 GUI,不确定是否需要。但不知道它是否想要,我没有投反对票。
      • 为什么要给 Swing 引入一个新的依赖?!在不确定他是否 GUI 的情况下,你甚至不应该建议这个解决方案。
      • 由于最后一段而被否决:守护线程正好相反:它是一个不会阻止 JVM 关闭的线程。如果运行 main 的线程是唯一的非守护线程,则 JVM 将关闭。
      • @Jaycee 如果他没有有图形用户界面,它不仅“不是最好的解决方案”,它只是一个错误的解决方案。不加思索地引入怪异的冗余依赖总是错误的解决方案。
      猜你喜欢
      • 2014-10-27
      • 2013-04-27
      • 2017-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多