Java ScheduledExecutorService等待资源可用

Java ScheduledExecutorService等待资源可用,java,multithreading,runnable,callable,Java,Multithreading,Runnable,Callable,我的java应用程序有问题。启动应用程序时,应用程序需要连接到另一个应用程序。我的想法是在我的应用程序启动时进行检查,每秒钟检查另一个应用程序是否可用没有等待5分钟之类的条件,只是无限期地等待,直到可用为止 我在下面的抽象示例中尝试了这一点。在此示例中,我的申请将在3次尝试后获得另一个申请 package main; import java.util.concurrent.Callable; import java.util.concurrent.CancellationException;

我的java应用程序有问题。启动应用程序时,应用程序需要连接到另一个应用程序。我的想法是在我的应用程序启动时进行检查,每秒钟检查另一个应用程序是否可用没有等待5分钟之类的条件,只是无限期地等待,直到可用为止

我在下面的抽象示例中尝试了这一点。在此示例中,我的申请将在3次尝试后获得另一个申请

package main;

import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Main {

    private static final Logger logger = LogManager.getLogger(Main.class);


    public static void main(String[] args) {

        final Callable<String> sleeper = new Callable<String>() {

            // local timer for resource getter
            ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
            ScheduledFuture<?> timer;

            String returnValue;

            @Override
            public String call() throws Exception {

                // start on first call
                if (null == timer) {
                    logger.info("sleeper - starting getter ...");
                    timer = executor.scheduleAtFixedRate(new getter(3), 0, 1, TimeUnit.SECONDS);
                }

                // the right way - this seems to be ugly!
                try {
                    timer.get(); 
                } catch (CancellationException | ExecutionException | InterruptedException e) {
                    logger.error("sleeper - got an exception ... but nothing bad?!");
                }

                logger.info("sleeper - returning="+returnValue);
                return returnValue;
            }

            class getter implements Runnable {
                int _trys;
                int _maxTrys;
                String _res = null;

                getter(int maxTrys) {
                    logger.info("getter - init, maxTrys=" + maxTrys);
                    _maxTrys=maxTrys;
                }
                @Override
                public void run() {

                    if (null == _res) {
                        if (_trys<_maxTrys) {
                            ++_trys;
                            logger.info("getter - sleeping trys="+_trys + "/" + _maxTrys);
                        } else {
                            _res = "*MIGHTY RESOURCE*";
                            logger.info("getter - found resource after "+_trys+" trys!");
                        }
                    } else {
                        logger.info("getter - returning resource to parent");
                        returnValue = _res; // hand over
                        this.notify(); // exit?
                    }
                }
            }
        };

        logger.info("Main - starting sleeper");
        ScheduledExecutorService sleeperExecutor = Executors.newScheduledThreadPool(1);
        Future<String> resource = sleeperExecutor.submit(sleeper);
        try {
            logger.info("Main - got="+resource.get());
        } catch (ExecutionException | InterruptedException e) {
            e.printStackTrace();
        }
    }

}
问候
S.

您要连接的资源是什么?数据库、web服务器、消息总线等?有一些资源,但主要资源是数据库。假设:数据库服务器托管在其他地方,您不尝试启动它。我会使用一个数据库连接池,例如,并假设在应用程序启动时一切正常。我不会写任何特殊的开始代码。在您的应用程序进程处于活动状态的整个生命周期中,数据库可能因任何原因在任何时候都无法访问-因此我认为没有任何特殊原因需要在应用程序启动时检查连接。希望这是有道理的。
Application {
    start() {

        while (!otherAppl.isAvailable) {
            // wait until other appl is available
        }

        // other application is available ... go on with startup
    }
}