У меня есть конвейер задач, которые нужно выполнить с файлами, каждый отдельный тип задачи выполняется внутри другой службы-исполнителя. После инициализации каждой службы-исполнителя я запускаю первую задачу, она гарантированно не завершится, пока не закончит обработку всех файлов, поскольку она обрабатывает папку, либо больше не требуется никакой работы, либо она отправляет вызываемую задачу в service2. Итак, когда вызов shutdown () для первой задачи завершился успешно, все файлы теперь будут обрабатываться в задаче 2 или другой задаче, находящейся ниже по конвейеру, и так далее. Когда мы сможем завершить работу последней службы, мы закончим.
Loader loader = Loader.getInstanceOf();
List<ExecutorService> services = new ArrayList<ExecutorService>();
ExecutorService es = Executors.newSingleThreadExecutor();
//Init Services
services.add(es);
services.add(task1.getService());
services.add(task2.getService());
services.add(task3.getService());
services.add(task4.getService());
//Start Loading Files
es.submit(loader);
int count = 0;
for (ExecutorService service : services)
{
service.shutdown();
count++;
//Now wait for all submitted tasks to complete, for upto one day per task
service.awaitTermination(10, TimeUnit.DAYS);
MainWindow.logger.severe("Shutdown Task:" + count);
}
public class AnalyserService
{
protected String threadGroup;
public AnalyserService(String threadGroup)
{
this.threadGroup=threadGroup;
}
protected ExecutorService executorService;
protected CompletionService completionService;
protected void initExecutorService()
{
int workerSize = Runtime.getRuntime().availableProcessors();
executorService
= Executors.newFixedThreadPool(workerSize, new SongKongThreadFactory(threadGroup));
}
public ExecutorService getService()
{
if (executorService == null || executorService.isShutdown())
{
initExecutorService();
}
return executorService;
}
}
Так что все работает нормально За исключением, у меня неправильная логика загрузки процессора. Каждая служба использует пул, равный количеству процессоров, имеющихся на компьютере. Итак, если у компьютера 4 процессора и у нас 5 служб, тогда у нас может быть 20 потоков, которые пытаются работать одновременно, перегружая процессор. Я думаю, что в этом случае у меня должно быть только 4 потока одновременно.
Если я ограничил каждую службу одним потоком, тогда у Id одновременно будет запущено только 5 потоков, но это все равно неправильно, потому что
- Больше не будет прав, если будет больше сервисов или больше процессоров
- Это неэффективно, так как основная часть работы будет выполняться с помощью задачи 1, если я ограничу ее одним процессором, она будет медленнее, чем необходимо, позже большинство потоков будет выполняться более поздними задачами, а задача 1 не будет иметь ничего сделать.
Я думаю, что мне нужно, чтобы все задачи разделяли одну службу исполнителя и устанавливали ее размер пула, равный количеству cput, которое имеет компьютер. Но тогда как мне узнать, когда услуга завершена?
Я использую Java 7, поэтому есть ли что-нибудь новое в Java 7, что может помочь, в настоящее время просто использую функции параллелизма Java 5