1

private ScheduledExecutorService pool = new ScheduledThreadPoolExecutor(20);

I'm running a task

public void run() {
    if (queue.isEmpty()) return;

    ArrayDeque<Profile> current = new ArrayDeque<Profile>();
    this.queue.drainTo(current, 20);

    MySQLStatement statement = this.wrapper.prepare();

    while (!current.isEmpty()) {
        if (statement.isClosed()) return;

        Profile profile = current.poll();
        statement.addBatch(profile.getId().toString(), ProfileBuilder.toJson(profile));
    }

    statement.executeBatchAsync();
}

using a ScheduledExecutorService

pool.scheduleAtFixedRate(new VerboseRunnable(runnable = new MySQLRunnable(this)), 250, 50, TimeUnit.MILLISECONDS);  

The MySQLRunnable stops working after some runs with a full queue, but it runs more or less infinite when the queue is empty.
First i thought the stops could be because of silently caught exception, so i added the VerboseRunnable

public void run() {
    try {
        runnable.run();
    } catch (Throwable e) {
        System.err.println("Error in runnable!");
        e.printStackTrace();
        throw new RuntimeException(e);
    }
}

But it still stops running. Also the ScheduledFuture tells me that the task is neither done nor cancelled.

Any help would be nice.

Jofkos
  • 739
  • 1
  • 9
  • 27
  • 1
    Are you closing your statements and connections? It might also be nice to show what `this.wrapper.prepare()` does? – dcsohl Aug 26 '15 at 17:50
  • @dcsohl Closing the statements is a good idea, that's most probably the solution. But why does the task stops running if i don't close them? – Jofkos Aug 26 '15 at 18:54
  • 1
    That's why I asked what `this.wrapper.prepare()` did ... because I'm not 100% certain. My guess, based on my knowledge, is that you are pulling connections from a connection pool ... the statement being open is blocking that connection, and so at a certain point when you ask for a new connection it will just hang... the default behaviour being to block until a connection is available (which usually isn't long unless there's a leak). – dcsohl Aug 26 '15 at 18:57
  • @dcsohl Yeah that's right, i'm pulling the connections out of a pool, i should have mentioned that in the first post. So you say that the pool "stops" giving out connections and simply freezes up the runnable at the point i try to get one? However, now i'm closing the statements and the connections, what does that until now it hasn't stopped running. – Jofkos Aug 26 '15 at 19:58
  • I think you're missing a few words; I'm not sure what you're asking. Is it working? But yeah, basically, if the pool is configured to go up to 20 connections, and it has 20 connections open, the 21st request will generally (depending on specific implementation) block and wait for one of the other connections to free up. I believe what you were seeing is your tasks blocking indefinitely because no connection got freed. – dcsohl Aug 26 '15 at 20:21
  • Yes, it is working! Thank you. – Jofkos Aug 27 '15 at 16:53

1 Answers1

3

You should always be careful to close resources as you use them, especially I/O resources like connections, statements, and result sets. In a pooled environment, you can very easily end up depleting the pool of connections, and subsequent tasks will end up blocking, waiting for a connection that may never be available (if you're lucky, depending on implementation etc, maybe connections will start closing themselves after a few minutes... or longer).

dcsohl
  • 7,186
  • 1
  • 26
  • 44