Java ScheduledExecutorService等待资源可用

时间:2015-02-17 12:25:22

标签: java multithreading runnable callable

我的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();
        }
    }

}

这似乎对我来说是一个糟糕的解决方案,因为我只能退出异常(请参阅timer.get())。对于这样一个简单的问题,似乎是非常敏捷的代码。

我想象这样的事情(伪代码):

Application {
    start() {

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

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

此致 S上。

0 个答案:

没有答案