Sample / best practice for connection access with undefined setup time
Below code tries to get a connection every 5 seconds. The getConnection method returns true or false depending on the random twin and for illustrative purposes. The time it takes to get a connection cannot be guaranteed, so if you don't get the initial connection, wait 5 seconds and try again. Once the connection is reached, just exit.
Is there a better / cleaner method for getting a connection instead of using if and Thread.sleep statements? It seems wrong (not sure why) sleeping the current thread for 5 seconds before trying again.
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;
}
}
source to share
I think that looping with Thread.sleep
is a good approach, especially if you want to include as many tries as possible, and since rebuilding InterruptedException
is most likely the best way to handle interrupts in a situation like this.
An alternative could be to use it ScheduledExecutorService
like this:
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);
or using 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);
If this pattern is used in multiple places, I would suggest creating a wrapper that accepts Runnable
(or even better Callable
).
On a related note, this is the exact code I'm using in one of my projects:
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);
}
source to share
I don't think the call Thread.sleep(5000)
is wrong in this case, but possibly dangerous in a larger application, I use CronTriggers QuartzScheduler for this purpose and it works very smoothly.
The CronTrigger with the declaration 0/5 * * * * ?
will be executed 5 seconds after the last initiated process ends. But there are many configurations.
source to share
Using is Thread.sleep()
bad practice
use Timer
instead
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);
source to share