访问具有不确定设置时间的连接的模式/最佳实践

时间:2015-05-26 10:40:49

标签: java design-patterns

以下代码尝试每5秒获取一次连接。 getConnection方法根据随机double返回true或false,并且是 用于说明目的。无法保证获得连接所需的时间,因此如果最初无法获得连接,请等待5秒钟 然后再试一次。一旦达到连接,然后退出。

是否有更好/更清晰的方法来获取连接而不是使用if语句和Thread.sleep?似乎错了(我不知道为什么)在再次尝试之前将正在运行的线程休眠5秒钟。

public class TestAlive {

    public static void main(String args[]) {

        while (true) {
            try {
                if (getConnection()) {
                    System.out.println("Got connection, do some work.....");
                    System.exit(0);
                }
                else {
                    System.out.println("No connection, re-trying in 5 seconds");
                    Thread.sleep(5000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static Boolean getConnection() {
        return Math.random() > 0.5;
    }
}

3 个答案:

答案 0 :(得分:2)

我认为使用Thread.sleep的循环是一种很好的方法,特别是如果要包含最大重试次数,并且因为重新抛出InterruptedException很可能是处理中断的最佳方法。像这样的情况。

另一种方法是使用ScheduledExecutorService,如下所示:

ScheduledExecutorService exec = new ScheduledThreadPoolExecutor(1);

exec.scheduleWithFixedDelay(() -> {
    if (getConnection()) {
        System.out.println("Got connection, do some work.....");
        System.exit(0);  // Or exec.shutdown();
    } else {
        System.out.println("No connection, re-trying in 5 seconds");
    }
}, 0, 5, TimeUnit.SECONDS);

或使用Timer

Timer timer = new Timer();
timer.schedule(new TimerTask() {
    public void run() {
        if (getConnection()) {
            System.out.println("Got connection, do some work.....");
            System.exit(0);  // And/or timer.cancel()
        } else {
            System.out.println("No connection, re-trying in 5 seconds");
        }
    }
}, new Date(), 5000);

如果在多个地方使用此模式,我建议您创建一个接受Runnable(甚至更好,Callable)的包装器。

在相关的说明中,这是我在我的一个项目中使用的确切代码:

int attempt = 0;
while (true) {
    Log.info("Trying to connect. Attempt " + (++attempt) + " of " + MAX_CONNECT_ATTEMPTS);
    try {
        return makeConnectionAttempt();
    } catch (IOException ex) {
        Log.error("Connection attempt failed: " + ex.getMessage());
        if (attempt >= MAX_CONNECT_ATTEMPTS) {
            Log.error("Giving up");
            throw new IOException("Could not connect to server", ex);
        }
    }
    Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS);
}

答案 1 :(得分:0)

我不认为在这种情况下调用Thread.sleep(5000)是错误的,但在更大的应用程序中可能会有危险,为此,我使用CronTriggersQuartzScheduler并且工作非常顺利。

具有声明0/5 * * * * ?的CronTrigger将在最后一个触发过程完成后5秒执行。但是有很多适用的配置。

答案 2 :(得分:0)

使用Thread.sleep()bad practise

使用Timer代替

timer = new Timer();

if (timer != null) {
    timer.scheduleAtFixedRate(new TimerTask() {
        public void run() {

            try {
                if (getConnection()) {
                    System.out.println("Got connection, do some work.....");
                    timer.cancel();
                    timer.purge();
                    System.exit(0);
                } else {
                    System.out.println("No connection, re-trying in 5 seconds");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }, 0, 5000);