я использование, которое DateTime Сравнивают правильно?
№
Compare
только предлагает информацию об относительном положении двух дат: меньше, равный или больше. То, что Вы хотите, является чем-то вроде этого:if ((expiryDate - DateTime.Now).TotalDays < 30) matchFound = true;
Это вычитает два
DateTime
с. РезультатTimeSpan
объект, который имеетTotalDays
свойство.Кроме того, условное выражение может быть записано непосредственно как:
matchFound = (expiryDate - DateTime.Now).TotalDays < 30;
Никакой
if
необходимый.
Вы действительно можете использовать ExecutorService
. Например, создайте новый фиксированный пул потоков с помощью метода newFixedThreadPool
. Таким образом, помимо кэширования потоков, вы также гарантируете, что одновременно выполняется не более n
потоков.
Что-то вроде этого:
private static final ExecutorService executor = Executors.newFixedThreadPool(N);
// ...
while (isOnJob) {
List<JobTask> tasks = getJobTasks();
if (!tasks.isEmpty()) {
List<Future<?>> futures = new ArrayList<Future<?>>();
for (final JobTask task : tasks) {
Future<?> future = executor.submit(new Runnable() {
@Override
public void run() {
task.doWork();
}
});
futures.add(future);
}
// you no longer need to use await
for (Future<?> fut : futures) {
fut.get();
}
}
}
Обратите внимание, что вам больше не нужно использовать защелку , поскольку get
будет ждать завершения вычисления, если это необходимо.
Я согласен с JG, что ExecutorService
- это то, что нужно ... но я думаю, что вы ' оба делают его более сложным, чем нужно.
Вместо того, чтобы создавать большое количество потоков (1 на задачу), почему бы просто не создать пул потоков фиксированного размера (с исполнителей. newFixedThreadPool (N)
) и передать ему все задачи? Не требуется семафор или что-то в этом роде - просто отправляйте задания в пул потоков по мере их получения, и пул потоков будет обрабатывать их с до N потоков за раз.
не собираетесь использовать более N потоков одновременно, зачем вам их создавать?
newFixedThreadPool (N) ) и передать ему все задачи? Не требуется семафор или что-то в этом роде - просто отправляйте задания в пул потоков по мере их получения, и пул потоков будет обрабатывать их с до N потоков за раз.не собираетесь использовать более N потоков одновременно, зачем вам их создавать?
newFixedThreadPool (N) ) и передать ему все задачи? Не требуется семафор или что-то в этом роде - просто отправляйте задания в пул потоков по мере их получения, и пул потоков будет обрабатывать их с до N потоков за раз.не собираетесь использовать более N потоков одновременно, зачем вам их создавать?
Используйте экземпляр ThreadPoolExecutor с несвязанной очередью и фиксированным максимальным размером потоков, например Executors.newFixedThreadPool (N) . Это позволит принять большое количество задач, но будет выполнять только N из них одновременно.
Если вместо этого вы выберете ограниченную очередь (с емкостью N ), то Executor отклонит выполнение задачи (насколько точно зависит от Политики, которую вы можете настроить при работе с ThreadPoolExecutor напрямую, вместо использования фабрики Executors - см. RejectedExecutionHandler ).
Если вам нужен «реальный» контроль перегрузки, вы должны установить границу BlockingQueue с емкостью N . Извлеките задачи, которые вы хотите выполнить, из базы данных и поместите их в очередь - если она заполнена, вызывающий поток заблокируется. В другом потоке (возможно, также начавшем использовать Executor API) вы берете задачи из BlockingQueue и отправляете их Executor . Если BlockingQueue пуст, вызывающий поток также будет заблокирован. Чтобы сигнализировать, что вы закончили, используйте «специальный» объект (например, синглтон, который отмечает последний / последний элемент в очереди).
В другом потоке (возможно, также начавшем использовать Executor API) вы берете задачи из BlockingQueue и отправляете их Executor . Если BlockingQueue пуст, вызывающий поток также будет заблокирован. Чтобы сигнализировать, что вы закончили, используйте «специальный» объект (например, синглтон, который отмечает последний / последний элемент в очереди). В другом потоке (возможно, также начавшем использовать Executor API) вы берете задачи из BlockingQueue и отправляете их Executor . Если BlockingQueue пуст, вызывающий поток также будет заблокирован. Чтобы сигнализировать, что вы закончили, используйте «специальный» объект (например, синглтон, который отмечает последний / последний элемент в очереди).Достижение хорошей производительности также зависит от типа работы, которая должна выполняться в потоках. Если ваша БД является узким местом в обработке, я бы начал обращать внимание на то, как ваши потоки обращаются к БД. Возможно, уместно использовать пул соединений. Это может помочь вам добиться большей пропускной способности, поскольку рабочие потоки могут повторно использовать соединения с БД из пула.