2015-08-26 3 views
1

private ScheduledExecutorService pool = new ScheduledThreadPoolExecutor(20);ScheduledExecutorService - задача прекращает работу

Я бегу задача

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(); 
} 

с использованием ScheduledExecutorService

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

MySQLRunnable перестает работать после нескольких прогонов с полной очереди, но это работает более или менее бесконечно, когда очередь пуста.
Сначала я подумал, что остановки может быть из-за беззвучно пойманной за исключением, поэтому я добавил VerboseRunnable

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

Но она по-прежнему перестает работать. Также ScheduledFuture сообщает мне, что задача не выполняется и не отменяется.

Любая помощь будет приятной.

+1

Вы закрываете свои заявления и соединения? Возможно, было бы неплохо показать, что делает 'this.wrapper.prepare()' делает? – dcsohl

+0

@dcsohl Закрытие утверждений - хорошая идея, это, скорее всего, решение. Но почему задача перестает работать, если я их не закрываю? – Jofkos

+1

Вот почему я спросил, что делает 'this.wrapper.prepare()' ... ... потому что я не уверен на 100%. Мое предположение, основываясь на моих знаниях, заключается в том, что вы подключаете соединения из пула соединений ... открытый оператор является блокировкой этого соединения, и поэтому в определенный момент, когда вы запрашиваете новое соединение, оно просто зависает ... поведение по умолчанию заключается в блокировке до тех пор, пока соединение не будет доступно (что обычно не долго, если нет утечки). – dcsohl

ответ

3

Вы всегда должны быть осторожны, чтобы закрыть ресурсы по мере их использования, особенно ресурсы ввода-вывода, такие как соединения, операторы и результирующие наборы. В объединенной среде вы можете очень легко исчерпать пул соединений, а последующие задачи в конечном итоге блокируются, ожидая подключения, которое никогда не будет доступно (если вам повезет, в зависимости от реализации и т. Д., Возможно, соединения начнутся закрывшись после нескольких минут ... или дольше).

+0

Как упоминалось выше, это исправило мою проблему. Спасибо! – Jofkos

+0

Yep - просто хотел сделать это в официальном ответе. – dcsohl