Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
2 / 1 / 1
Регистрация: 24.04.2010
Сообщений: 76

Чтение файла через ForkJoinPool

14.03.2019, 11:02. Показов 878. Ответов 1

Студворк — интернет-сервис помощи студентам
Есть большой файл, около 500К строк. В каждой строке файла есть идентификатор , характеризующий одну из 50 таблиц (энтити, класс). Мне надо как-то очень оптимально пробежаться по этому файлу, достать каждую строку и кинуть её в уже написанный обрабтчик. Мне настоятельно рекомендовали использовать ForkJoinPool. Пока не получается то, что хочется.

Запуск в методе разбора файла
Java
1
2
3
4
5
6
    public void parseFile() {
        ForkJoinPool pool = new ForkJoinPool(4);
        FileParserProcessor fileParser = new FileParserProcessor("MyBigFile.txt", 24);
        pool.invoke(fileParser);
        pool.shutdown();
    }
Моя неправильная реализация:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class FileParserProcessor extends RecursiveAction {
    private long workLoad = 0;
    private String path;
 
    public FileParserProcessor(String path, long workLoad) {
        this.workLoad = workLoad;
        this.path = path;
    }
 
 
    @Override
    protected void compute() {
        //if work is above threshold, break tasks up into smaller tasks
        if(this.workLoad > 16) {
 
            List<FileParserProcessor> subtasks =
                    new ArrayList<FileParserProcessor>(createSubtasks());
 
            for(RecursiveAction subtask : subtasks){
                subtask.fork();
            }
 
        } else {
            try (BufferedReader br = new BufferedReader(
                    // TODO: to make file upload via interface
                    new FileReader(path)
            )) {
                String line;
                while ((line = br.readLine()) != null) {
                    System.out.println(line);
                }
            } catch (FileNotFoundException e) {
                throw new RuntimeException("An error occurred: file not found", e);
            } catch (IOException e) {
                throw new RuntimeException("An error occurred while parsing file", e);
            }
        }
    }
 
    private List<FileParserProcessor> createSubtasks() {
        List<FileParserProcessor> subtasks =
                new ArrayList<FileParserProcessor>();
 
        FileParserProcessor subtask1 = new FileParserProcessor(path, this.workLoad / 2);
        FileParserProcessor subtask2 = new FileParserProcessor(path, this.workLoad / 2);
 
        subtasks.add(subtask1);
        subtasks.add(subtask2);
 
        return subtasks;
    }
}
Добавлено через 6 минут
При этом я нашёл вариант решения через ExecutorService. Плохо только то, что нужно знать количество строк, чтобы задать capacity в BlockingQueue. Подразумевается, что впоследствии файлы будут загружаться пользователем, поэтому количество строк может быть каким угодно.

Найденное решение через ExecutorService:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    public void parseFile() {
        final int threadCount = Runtime.getRuntime().availableProcessors();
        BlockingQueue<String> queue = new ArrayBlockingQueue<String>(2000000);
        // create thread pool with given size
        ExecutorService service = Executors.newFixedThreadPool(threadCount);
        for (int i = 0; i < (threadCount - 1); i++) {
                service.submit(new CPUTask(queue));
        }
        // Wait til FileTask completes
        try {
            service.submit(new FileTask(queue)).get();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException("An error .......................................", e);
        }
        service.shutdownNow();  // interrupt CPUTasks
        // Wait til CPUTasks terminate
        try {
            service.awaitTermination(5, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            throw new RuntimeException("An error occurred when terminate parsing process by timeout", e);
        }
    }
 
    class CPUTask implements Runnable {
        private final BlockingQueue<String> queue;
 
        public CPUTask(BlockingQueue<String> queue) {
            this.queue = queue;
        }
 
        public void run() {
            String line;
 
            while (true) {
                try {
                    // block if the queue is empty
                    line = queue.take();
 
                    System.out.println(line);
 
                    // do things with line
                } catch (InterruptedException ex) {
                    break; // FileTask has completed
                }
            }
        }
    }
 
    class FileTask implements Runnable {
        private final BlockingQueue<String> queue;
 
        public FileTask(BlockingQueue<String> queue) {
            this.queue = queue;
        }
 
        public void run() {
            try (BufferedReader br = new BufferedReader(
                    // TODO: to make file upload via interface
                    new FileReader("MyVeryBigFile.txt")
            )) {
                String line;
                while ((line = br.readLine()) != null) {
                    // block if the queue is full
                    queue.put(line);
                }
            } catch (FileNotFoundException e) {
                throw new RuntimeException("An error occurred: file not found", e);
            } catch (IOException | InterruptedException e) {
                throw new RuntimeException("An error occurred while parsing file", e);
            }
        }
    }
Добавлено через 22 минуты
А через параллельные стримы будет оптимально? вот так, например:

Java
1
2
3
4
5
6
7
8
9
    public void parseFile() {
        try {
            Stream<String> lines = Files.lines(Paths.get("MyBigFile.txt"));
            lines.parallel()
                    .forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.03.2019, 11:02
Ответы с готовыми решениями:

Как заменить чтение строки из консоли на чтение текстового файла?
основное задание: найти частоту суффикса (например, &quot;ing&quot;) в текстовом документе. в прикреплённом коде текст вводится прямо в консоль,...

Запись файла через одно приложение, а чтение через другое
Есть 2 консольные программы. 1-я пишет в файл &quot;z&quot; текст, 2-я читает с файла &quot;z&quot; этот текст и работает с ним. Подскажите как...

Чтение файла через while
Делаю лабу, но не знаю какое условие писать в while ибо обычное !feof(file) не подходит, выдаёт ошибку. void Read_Data_Base(Data_base ...

1
Эксперт Java
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
14.03.2019, 11:40
Цитата Сообщение от maksimka2112 Посмотреть сообщение
А через параллельные стримы будет оптимально? вот так, например:
ты же знаешь, что можешь запустить код и посмотреть? Скорее всего читать один файл в несколько потоков смысла нет
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
14.03.2019, 11:40
Помогаю со студенческими работами здесь

Чтение из файла через класс
Здравствуйте! У меня нубский вопрос... Имеется класс формы (Form1) с обработчиком события button1_Click public partial class...

Чтение из файла через fscanf
Файл такого содержания petrov 4305 5.000000 sidorov 4306 4.000000 пытаюсь записать в массив через функцию while (((fscanf(data,...

Чтение файла через API
Доброго времени суток! Создаю здесь тему повторно т.к в разделе Win Api никто не читает изменил код для удобства. Помогите разобраться...

Чтение xml файла через for
Здравствуйте, как сделать так, чтобы progressbar работал по мере добавления, знаю, как сделать через for, но не знаю, как двигать...

Чтение файла через fstream
прочитать из файла матрицу и записать в новый файл её минимальный элемент в первой строке задана размерность матрицы файл: 10 8 ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
2
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru