1

EDIT:
The current code is the working solution, the one which does not block the application, it incorporates the suggestion made in the approved answer.


I want a background thread to download an MS Access database continuously, while my tomcat 7 web application is running, the thread does download the database, however it seems to block my application's startup as I'm unable to access any page from the service, this is the code that I'm using:

public class DatabaseUpdater implements ServletContextListener {
    private Thread thread = null;

    private final Runnable updater = new Runnable() {

        private boolean hasExpired(File mdbFile) throws IOException {
            if (!mdbFile.exists())
                return true;

            Long ttl = Long.parseLong(Configuration.getValueForOS("db.http-expiration"));

            Date now = new Date();
            Date fileDate = new Date(mdbFile.lastModified());

            return (now.getTime() - fileDate.getTime()) > ttl;
        }

        @Override
        public void run() {
            while (true) {
                if (Thread.currentThread().isInterrupted())
                    throw new RuntimeException("Application Shutdown");

                try {
                    String databases[] = new String[]{"database1", "database2"};
                    for (String database : databases) {

                        String fileName = database + "." + StringUtil.randomString(8) + ".mdb";
                        String fileLocation = Configuration.getValueForOS("db.path");

                        File mdbFile = new File(fileLocation, fileName);
                        File currentDatabaseFile = new File(fileLocation, database + ".mdb");

                        if (hasExpired(currentDatabaseFile)) {
                            URL url = new URL(Configuration.getValueForOS("db.url." + database));
                            InputStream in = url.openConnection().getInputStream();
                            OutputStream out = new FileOutputStream(mdbFile);

                            FileUtil.streamBridge(in, out);
                            FileUtil.close(in, out);

                            while (currentDatabaseFile.exists() && !currentDatabaseFile.delete()) ;
                            while (!mdbFile.renameTo(currentDatabaseFile)) ;
                       }
                   }
                     // Put the thread to sleep so the other threads do not starve
                    Thread.sleep(Long.parseLong(
                        Configuration.getValueForOS("db.http-expiration"));
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                }
            }
        }
    };

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        this.thread = new Thread(updater);
        thread.start();
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        if (this.thread.isAlive())
            this.thread.interrupt();
    }
}

What could be causing?

I based my implementation on this question: Background Thread for a Tomcat servlet app

Community
  • 1
  • 1
Tristian
  • 3,001
  • 5
  • 24
  • 44

1 Answers1

1

Given that your code loops forever, you're probably starving all the other threads in the VM. Try sleeping the thread once in a while.

Ryan Stewart
  • 115,853
  • 19
  • 167
  • 192
  • Nice observation, thanks, in your experience, what would qualify like a "while", every `N` times or every `N` seconds? – Tristian Dec 21 '12 at 22:10
  • Too many variables to guess at... It's some function of how "real-time" you need that database stuff to be, how responsive your webapp needs to be to how many users, and how many resources (RAM, CPU) you have to throw at it. I'd just play with the numbers to find a spot you're happy with. Use a tool like [VisualVM](http://visualvm.java.net/) or the [java command-line monitoring and debugging tools](http://docs.oracle.com/javase/7/docs/technotes/tools/index.html) to monitor resource usage. – Ryan Stewart Dec 21 '12 at 22:16