I’m reviewing Java code that essentially is a recurring process that moves/reads/parses some files on regular basis and outputs data into the database. The repeating part is done (roughly) as follows:
public class CollectorMain {
public static boolean signalRecieved = false;
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
shutdown();
}});
while(!signalRecieved) {
Collector.execute();
try {
Thread.sleep(60 * 1000);
} catch (InterruptedException e) {
break;
}
}
// some shutdown logic
}
public static void shutdown() {
signalReceived = true;
}
}
public class Collector() {
public static void execute() {
// Move files from the queue dir to temp location
// Read, parse files and insert records into database.
// Then delete the processed files
}
}
My recommendation was to refactor code to
- Create instance of Collector and refactor static execute() method to the instance method
- To use Runnable or TimerTask to handle invocations
My argument was that using Thread.wait from the main method and combining it with static access is not a good way of handling repeatable process especially doing file IO. To which the author replied (quoting)
The description of Runnable says “should be implemented by any class
whose instances are intended to be executed by a thread”. In fact, I
am intentionally avoiding threads in this program, for reasons of cost
vrs.performance requirements.
Here’s another quote from same discussion which will hopefully help to clarify the author’s position
Technically, Java isn’t executed at all, it is interpreted by the JVM
which then executes machine instructions, to simulate that the Java
code is executing. So it’s really the JVM that is executing on a
thread, or multiple threads.But as a Java code writer, I don’t care. If I don’t create “threads”
in Java, then It’s the job of the JVM to appear as if there are no
threads — even if the JVM is using threads “under the covers”.A Java Pause is not executed, it is simulated by a sequence of machine
instructions that may or may not call an OS ‘wait’. (It probably does,
because the JVM would not want to spin, burning CPU cycles, but that’s
a JVM implementation choice).
So I have 2 questions:
- Is putting
Thread.waitinto the main method legit, safe and advisable way of doing repeatable task in this instance? And if not, why not since there’s only one (main) thread of execution? - What are the pitfals of using static metods in this context (if any)?
I’ll be happy to provide additional info if you have any other questions.
You’re really arguing about design decisions, not performance decisions.
Your colleague’s statement about how Thread.sleep is implemented is basically incorrect as far as I can see. On a sensible JVM on a sensible operating system, Thread.sleep() is implemented using an O/S native method for parking a thread (or putting it in a “timed wait” state or whatever you want to call it on your OS). Or put another way, while a thread is sleeping, it consumes zero CPU. And in any case, TimerTask will use Thread.sleep (or similar– I don’t just recall if it uses the park() method introduced in Java 5, but it essentially makes no difference).
The JVM won’t generally make secret under-the-hood decisions about threading. If you ask for another thread, you’ll get one; if you don’t, you won’t. A few “housekeeping” threads will be created for garbage collection etc, but as far as your code is concerned, you can assume that no secret clever thread creation is going on.
So, coming back to your questions: