创建一个等待Java中的Thread的main()循环的黄金标准是什么?

时间:2017-06-08 12:27:27

标签: java oop 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);
            }

thread.sleep好吗?我甚至可以省略它吗?我想在我的代码的这一点上等待,所以我可以在执行停止后清理。

3 个答案:

答案 0 :(得分:3)

您可以将服务器设为 runnable ,将其打包到线程中并加入!

实施例

my $d = $rep->GetCurrentDiagram();
for my $dl (in $d->DiagramLinks) {
  print $dl->Geometry . "\n";
  $dl->{Geometry} = 'SX=0;SY=10;EX=0;EY=0;';
  $dl->Update();
}
$rep->ReloadDiagram($d->DiagramId);

答案 1 :(得分: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,您可以创建多个服务器实例并在主线程中等待它们,直到它们全部完成。

答案 2 :(得分:1)

这取决于你如何管理你的线程。

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

serverThread.join();

查看Thread API以获取更多选项,例如在join()上设置超时(这样您就可以采取越来越激烈的措施来结束)。

更高级别的线程抽象,例如ExecutorFutureForkJoinTask等,可以为您提供不同API的相同功能。对这些内容的全面探索超出了SO答案的范围 - Oracle提供了有关并发的教程,或者有书籍。