有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

oop在Java中创建等待线程的main()循环的黄金标准是什么

我的任务是编写一个小型服务器应用程序。它应该通过控制台启动,然后在后台运行,处理一些网络流量并在本地计算数据,直到收到关机信号。我非常确信我可以处理所有这些-除了非常基本的应用程序架构。我非常不确定如何使我的主循环等待应用程序完成。这是我当前的代码,经过清理并省略了不必要的部分

public class TestServer {

public static Logger logger;
private static Boolean abortStartup = false;
private static ServerModule server;

public static void main(String[] args) {
    System.out.println("Starting Server...");
        initializeServer(); //this function reads config file, and initializes all variables and stuff. If anything goes wrong, abortStartup is set to true

        if (!abortStartup) {
            runMainLoop();              
        }

        if (!abortStartup) {
            cleanup(); //clean up all initialized variables and objects
        }

    System.out.println("Goodbye.");
}


private static void runMainLoop() {
    //This is the main loop. Run this until application terminates.
    logger.log(null, "Starting main loop...", Logger.LOGLEVEL_NOTE);
        server.run();
        while (server.isAlive()) {
            //wait until server dies.
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                logger.log(null, "Interrupted during wait for main thread.", Logger.LOGLEVEL_ERROR);
            }
        }
    logger.log(null, "Done.", Logger.LOGLEVEL_NOTE);
}

ServerModule如下所示:

public class ServerModule{

public Boolean shutdown = false;
private Boolean stayAlive = true;


public ServerModule(){
    //setup everything
}

public void run() {
    //initalize timers, instantiate objects etc.. add listeners and everything. At some point, a network message will set stayAlive to false;
}

public Boolean isAlive() {
    return stayAlive;
}

现在来看看实际的问题:有没有更优雅或更有效的方法?我具体讲的是这一部分:

while (server.isAlive()) {
            //wait until server dies.
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                logger.log(null, "Interrupted during wait for main thread.", Logger.LOGLEVEL_ERROR);
            }

这是线。在这里睡得好吗?我可以或者应该忽略它吗?我想在这里等待代码的这一点,以便在执行停止后进行清理


共 (3) 个答案

  1. # 1 楼答案

    你可以让你的服务器运行起来,把它打包成一个线程并加入

    范例

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            try {
                Thread.sleep(5000L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println("Starting Server!");
        t.start();
        t.join();
        System.out.println("Server is done!");
    
    }
    
  2. # 2 楼答案

    这取决于您如何管理线程

    在最低级别的Java线程API中,主线程可以等待服务器线程完成以下操作:

    serverThread.join();
    

    查看线程API以获得更多选项,例如在join()上设置超时(因此您可以采取越来越激烈的措施来结束它)

    更高级的线程抽象,如ExecutorFutureForkJoinTask等,为您提供了使用不同API的相同能力。对这些问题的深入研究超出了答案的范围,所以Oracle有关于并发性的教程,或者有很多书

  3. # 3 楼答案

    您也可以出于自己的目的使用CountDownLatch,请参见示例:

    public class ServerModule extends Thread {
        private final CountDownLatch latch;
    
        ServerModule(CountDownLatch latch) {
            this.latch = latch;
        }
    
        @Override
        public void run() {
            try {
                Thread.sleep(1000L);
                //decrease counter of the latch when job is done
                latch.countDown();
            } catch (InterruptedException e) {
                 e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            // as ctor arg use threads count for countdown
            CountDownLatch latch = new CountDownLatch(1);
            System.out.println("Start server");
            ServerModule serverModule = new ServerModule(latch);
            serverModule.start();
    
            try {
                //waiting until latch count will be 0
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Server is done");
        }
    }
    

    同样,通过CountDownLatch,您可以创建多个服务器实例,并在主线程中等待它们,直到它们全部完成