Я пытаюсь переписать приложение C# на Spring Boot Java. Приложение C# создает около 150 больших файлов с помощью Parallel.ForEach
и завершается менее чем за 8 минут, тогда как приложение Java занимает около 20 минут
Parallel.ForEach(
_ClientFileList,
new ParallelOptions() { MaxDegreeOfParallelism = FileCreation_ThreadQuantity },
x => CreateFile(x)
);
Программа сначала вызывает хранимую процедуру, которая возвращает набор результатов с информацией, необходимой для создания файла. Каждая строка результирующего набора содержит идентификатор файла, путь для сохранения файла и имя (другой процедуры хранения), которая получает
данные для помещения в файл. Каждая строка этого набора результатов сохраняется в объекте ClientFile, добавленном в список, который называется client_file_info.
Методprocess() затем берет время из списка и вызывает каждую хранимую процедуру (которая и записывает данные, возвращаемые
хранимой процедурой, по указанному пути.
Вот метод Process(), использующий BufferedWriter.
public void process(ClientFile client_file)
{
BufferedWriter writer = new BufferedWriter(new FileWriter(exportFile.FileDestination), 65536); //65536 32768
BufferedWriter ftpWriter = new BufferedWriter(new FileWriter(exportFile.FTPDestination), 65536);
CallableStatement callableStatement = connection.prepareCall("call getInfo (?) }") //Code of proc not important
int i = 0;
callableStatement.setString(++i, client_file.id);
ResultSet files = ResultSet rs = callableStatement.getResultSet();
if(files != null)
{
while(files.next())
{
writer.write
}
}
}
Я попробовал использовать параллельныйStream() в методе run() следующим образом, но это заняло около 30 минут, что
столько же времени потребовалось до добавления "многопоточности" .
private ClientFile client_file;
private List client_file_list = new ArrayList();
public void run(String... args) {
client_file_list = getClientFileList();
client_file_list.parallelStream().forEach(x -> { client_file.process(x); } );
}
Я также пробовал использовать CompletableFutures в методе run(). Вывод показывает, что используется 15 потоков, но, очевидно,
все еще работает в одном потоке. Я добавил @Async в методprocess() при использовании Completable Futures и создал объект
ThreadPoolTaskExecutor (показан ниже). Что еще нужно сделать для работы в нескольких потоках?
public void run(String... args) {
CompletableFuture future = CompletableFuture.runAsync(() -> {
client_file_info.forEach( x -> {client_file.process(x); });
});
}
В отдельном файле я определил объект ThreadPoolTaskExecutor:
@Bean(name = "asyncExecutor")
public ThreadPoolTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(15);
executor.setMaxPoolSize(20);
executor.setQueueCapacity(2050);
executor.setThreadNamePrefix("poolThread-");
executor.initialize();
return executor; }
Подробнее здесь: https://stackoverflow.com/questions/790 ... ltaneously