在所有线程完成后退出Java程序

在所有线程完成后退出Java程序,java,multithreading,runtime,Java,Multithreading,Runtime,我有一个密码保存程序,可以将密码保存到文本文件中。用户可以添加或删除密码,数据将重新写入文本文件。为了防止程序变得非常慢,每次程序需要保存时,我都会创建一个新线程。我有一个扩展线程的类,它将所有数据写入指定的文本文件。我遇到的问题是,当我试图在用户想要退出之前保存所有数据时。当按下退出按钮时,我创建一个新线程来保存数据,然后调用System.exit()函数退出 Thread t = new SaveThread(); t.start(); System.exit(0); 我注意到程序将在线程

我有一个密码保存程序,可以将密码保存到文本文件中。用户可以添加或删除密码,数据将重新写入文本文件。为了防止程序变得非常慢,每次程序需要保存时,我都会创建一个新线程。我有一个扩展线程的类,它将所有数据写入指定的文本文件。我遇到的问题是,当我试图在用户想要退出之前保存所有数据时。当按下退出按钮时,我创建一个新线程来保存数据,然后调用System.exit()函数退出

Thread t = new SaveThread();
t.start();
System.exit(0);
我注意到程序将在线程完成之前退出。有没有什么方法可以让java只在线程停止运行时退出?

您可以使用它注册应该在JVM关闭之前运行的代码


您可以使用
Thread.join()
等待线程

您有几种选择:

  • 在调用
    System.exit()
    之前,请在每个线程上调用
    thread.join()
  • 不要调用
    System.exit()
    ,而是让主线程从其
    main()
    函数返回。这将等待所有非守护进程线程在进程关闭之前终止

  • 如果
    SaveThread
    是要执行的最后一个操作,为什么不将
    System.exit()
    调用移动到该线程中


    大家同意,有更好的解决方案,但如果您想使用此方法并多次使用此save线程的实例,则可以轻松地将其参数化:

    public SaveThread extends Thread {
    
       private exitAfterSave = false;
    
       public SaveThread() {
         this(false);
       }
    
       public SaveThread(boolean exitAfterSave) {
         this.exitAfterSave = exitAfterSave;
       }
    
       @Overwrite
       public void run() {
    
          // Save what has to be saved
    
          if (exitAfterSave) {
            System.exit(0);
          }
       }
    }
    

    您有三种选择:

  • 启动线程后调用
  • 使用代替
  • 通过将保存线程添加为关机挂钩
  • 选项1

    这个很简单:

    Thread t = new SaveThread();
    t.start();
    t.join();
    System.exit(0);
    
    选项2

    也很简单:

    Thread t = new SaveThread();
    t.run();
    System.exit(0);
    
    选项3

    这也很容易,但在应用程序启动时就可以完成。在应用程序初始化代码中,执行以下操作:

    Runtime.getRuntime().addShutdownHook(new SaveThread());
    

    当应用程序关闭时,它将自动运行。

    当然可以在退出之前调用
    t.join()
    。不要为线程设置“daemon”标志,JVM将等待所有后台线程的完成。为什么保存文本文件这么慢?这是我遇到的第一个问题mind@Gray:您可以将您的评论作为答案发布。@jdevelop只有在有10多个密码时才会出现问题,每个密码有5行,因此需要写入50行文本。我猜程序会在所有行都可以写入之前退出。因为当我不希望程序退出时,整个程序会多次调用save线程。