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

Многопоточность и работа с файлами

23.10.2019, 23:36. Показов 5014. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Поставили задачу, реализовать приложение у которого:

Имеется 3 потока, а также 2 файла

1 поток записывает каждую секунду некоторое случайное число в файл journal_1.txt
2 поток просматривает каждую секунду файл journal_1.txt и записывает сумму последних двух записанных в этот файл чисел в файл journal_2.txt
3 поток просматривает каждую секунду файл journal_2.txt и записывает сумму последних двух записанных в этот файл в файл journal_1.txt

С потоками знаком плохо, потому возникли проблемы с реализацией. Попробовал сделать 3 класса под 3 потока, который как-то пытались реализовать поставленную задачу. Однако, пока что правильно отрабатывает лишь 1 поток. Второй класс некорректно забирает данные из файла journal_1.txt

Исходный код основного класса
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package application;
 
public class Threads_question {
    public static void main(String[] args) throws InterruptedException {
        First_Thread first_thread = new First_Thread();
        Second_Thread second_thread = new Second_Thread();
        Third_Thread third_thread = new Third_Thread();
        while(true){
            first_thread.run();
            first_thread.sleep();
            second_thread.run();
            second_thread.sleep();
        }
    }
}
Исходный код класса, отвечающего за 1 поток
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
package application;
 
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
 
public class First_Thread implements Runnable {
    private int num = 1;
 
    private int get_num(){
        return this.num;
    }
 
    void sleep() throws InterruptedException {
        Thread.sleep(1000);
    }
 
    @Override
    public void run() {
        String filePath = "journal_1.txt";
        String text = Integer.toString(get_num());
        try {
           // System.out.println(num++);
            Files.write(Paths.get(filePath), text.getBytes(), StandardOpenOption.APPEND);
        }
        catch (Exception e){
            System.out.println("Не удалось открыть файл!");
        }
    }
}
Исходный код класса, отвечающий за 2 поток
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
package application;
 
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
 
public class Second_Thread implements Runnable {
 
    void sleep() throws InterruptedException {
        Thread.sleep(1000);
    }
 
    @Override
    public void run() {
        List<Integer> num_list = new ArrayList<>();
        String filePath = "journal_2.txt";
        try(FileReader reader = new FileReader("journal_1.txt"))
        {
            // читаем посимвольно
            int c;
            int sum = 0;
            while((c = reader.read()) != -1){
                num_list.add(Integer.parseInt((char) c + ""));
                for(int index = 0; index < num_list.size(); ++index){
                    if(index % 2 != 0 ){
                        int rez = num_list.get(index) + num_list.get(index - 1);
                        System.out.println(rez);
                        String text = Integer.toString(rez);
                        try {
                            Files.write(Paths.get(filePath), text.getBytes(), StandardOpenOption.APPEND);
                        }
                        catch (Exception e){
                            System.out.println("Не удалось открыть файл!");
                        }
                    }
                }
            }
        }
        catch(IOException ex){
 
            System.out.println(ex.getMessage());
        }
    }
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.10.2019, 23:36
Ответы с готовыми решениями:

Многопоточность при работе с файлами
Доброй ночи! Написал код для сравнения двух файлов: string text, text2; bool write = true; a...

Работа с файлами , хотелось бы с windows system файлами
всем привет, нужна интересная идея по программированию, работа с файлами , хотелось бы с windows system файлами, у вас есть какая-то идея?...

Многопоточность и работа с COM-портом
Добрый день. Необходимо реализовать программу, которая будет непрерывно читать из com-порта(желательно, чтобы операция чтения выполнялась...

15
 Аватар для Goongala
1022 / 562 / 185
Регистрация: 18.08.2013
Сообщений: 2,027
Записей в блоге: 2
24.10.2019, 05:48
Чувак, зачем ты у них sleep вызываешь? Их надо просто запустить и забыть про них

Добавлено через 1 минуту
И оборачивай их в Thread
0
1 / 1 / 1
Регистрация: 11.07.2018
Сообщений: 96
24.10.2019, 15:52  [ТС]
sleep вызывается, чтобы в файл записывались значения через каждую 1 с., а не через каждые микросекунды. Что значит оборачивать их в Thread? Разве Runnable не производит этого?
0
 Аватар для Goongala
1022 / 562 / 185
Регистрация: 18.08.2013
Сообщений: 2,027
Записей в блоге: 2
24.10.2019, 16:02
Цитата Сообщение от W014ara Посмотреть сообщение
Разве Runnable не производит этого?
Нет. Нельзя вручную вызывать метод run у Runnable, надо оборачивать в Thread. Цикл чтения и записи сделай внутри Runnable и если надо, то добавь туда sleep()
0
Эксперт Java
3639 / 2971 / 918
Регистрация: 05.07.2013
Сообщений: 14,220
24.10.2019, 16:12
Цитата Сообщение от Gungala Посмотреть сообщение
Нельзя вручную вызывать метод run у Runnable
можно, кто ж мешает. Просто результат другой.
0
1 / 1 / 1
Регистрация: 11.07.2018
Сообщений: 96
25.10.2019, 00:43  [ТС]
Gungala
Вы имеете ввиду сделать такую конструкцию?
Java
1
2
First_Thread first_thread = new First_Thread();
new Thread(first_thread).start();
0
 Аватар для Goongala
1022 / 562 / 185
Регистрация: 18.08.2013
Сообщений: 2,027
Записей в блоге: 2
25.10.2019, 05:58
Ага
0
1 / 1 / 1
Регистрация: 11.07.2018
Сообщений: 96
25.10.2019, 10:06  [ТС]
Gungala
Спасибо, теперь тогда вопрос по самой работе программы. Первый класс все хорошо делает, добавляет в journal_1.txt какие-то цифры каждую секунду. Проблема возникает со вторым классом (реализовывать 3-ий не было смысла, ибо он аналогичен, как я понял 2-ому, только проверять будет уже journal_2.txt). Каждый раз при отработке метода start у второго класса, он кидает полностью обновленный список в journal_1.txt
Например, 1 поток закинул в 1 файл цифры: 1 1 2 3
Второй поток выводит следующее:
2
2
3
2
3
5

Полагаю, что косяк в постоянном пересоздании ArrayList, но как решать подобный траб не понимаю. Есть ли способ, например, как-то достать именно последние 2 строки в файле, при этом не закрывая его?
0
 Аватар для Goongala
1022 / 562 / 185
Регистрация: 18.08.2013
Сообщений: 2,027
Записей в блоге: 2
25.10.2019, 11:17
Как вариант
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
import java.io.*;
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
 
public class Test {
    public static void main(String[] args) {
        Thread first = new Thread(() -> {
            Random rand = ThreadLocalRandom.current();
            String path = Test.class.getResource("text").getPath();
            
            try (PrintWriter pw = new PrintWriter(new FileWriter(path, true), true)) {
                while (true) {
                    pw.println(rand.nextInt(100));
                    Thread.sleep(1000);
                }
            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        Thread second = new Thread(() -> {
            int[] nums = new int[2];
            int index = 0;
            try (Scanner in = new Scanner(Test.class.getResourceAsStream("text"), "UTF-8")) {
                while (true) {
                    nums[index++] = in.nextInt();
                    if (index == 2) {
                        index = 0;
                    }
                    
                    System.out.println(nums[0] + nums[1]);
                    Thread.sleep(1000);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        first.start();
        second.start();
    }
}
0
1 / 1 / 1
Регистрация: 11.07.2018
Сообщений: 96
25.10.2019, 13:50  [ТС]
Gungala

Компилятор кричит на ошибку в строчке.
Java
1
try (Scanner in = new Scanner(Test.class.getResourceAsStream("text.txt"), "UTF-8"))
Не особо понимаю, файл вроде бы существует и первый поток записывает в него данные, но вот 2 поток уже кричит.
0
 Аватар для Goongala
1022 / 562 / 185
Регистрация: 18.08.2013
Сообщений: 2,027
Записей в блоге: 2
25.10.2019, 15:31
Файл "text.txt" должен лежать в той же директории, что файл класса
0
1 / 1 / 1
Регистрация: 11.07.2018
Сообщений: 96
26.10.2019, 02:18  [ТС]
Gungala

Попытался сделать следующим образом:

Основной класс программы
Java
1
2
3
4
5
6
7
8
9
10
package application;
 
public class Test {
    public static void main(String[] args) throws InterruptedException {
        First_Thread first_thread = new First_Thread();
        Second_Thread second_thread = new Second_Thread();
        new Thread(first_thread).start();
        new Thread(second_thread).start();
    }
}

Класс, отвечающий за первый поток
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
package application;
 
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
 
public class First_Thread implements Runnable {
    @Override
    public void run() {
        Random rand = ThreadLocalRandom.current();
        String path = "text.txt";
 
        try (PrintWriter pw = new PrintWriter(new FileWriter(path, true), true)) {
            while (true) {
                int digit = rand.nextInt(100);
                System.out.println(digit);
                pw.println(digit);
                Thread.sleep(1000);
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}
Класс, отвечающий за 2 поток

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
package application;
 
import java.io.*;
import java.nio.file.Paths;
import java.util.Scanner;
 
 
public class Second_Thread implements Runnable {
    @Override
    public void run() {
        String path = "text_1.txt";
        int[] nums = new int[2];
        int index = 0;
        try (Scanner in = new Scanner(Paths.get("text.txt"), "UTF-8")) {
            while (true) {
                nums[index++] = in.nextInt();
                if (index == 2) {
                    index = 0;
                }
                String digit = Integer.toString(nums[0] + nums[1]);
                System.out.println("Второй поток сложил числа: " + nums[0] + " и " + nums[1] +
                        " - получил в результате число: " + digit);
                try (PrintWriter pw = new PrintWriter(new FileWriter(path, true), true)) {
                        pw.println(digit);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                Thread.sleep(1000);
            }
        } catch (InterruptedException | IOException e) {
            System.out.println("error");
        }
    }
}
Появились следующий проблемы:

1) Если делать класс 3, аналогичный классу 2, просто поменяв названия файлов, то возникает ошибка (когда оба файла пустые);
2) При повторном перезапуске программы 2 поток начинает суммировать все числа из файла text.txt заново, вместо того, чтобы продолжить просто вносить изменения.

Как можно решить данные проблемы?

Добавлено через 8 минут
Класс, отвечающий за 3 поток соответственно:

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
package application;
 
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Paths;
import java.util.Scanner;
 
public class Third_Thread implements Runnable {
    @Override
    public void run() {
        String path = "text.txt";
        int[] nums = new int[2];
        int index = 0;
        try (Scanner in = new Scanner(Paths.get("text_1.txt"), "UTF-8")) {
            while (true) {
                nums[index++] = in.nextInt();
                if (index == 2) {
                    index = 0;
                }
                String digit = Integer.toString(nums[0] + nums[1]);
                System.out.println("Третий поток сложил числа: " + nums[0] + " и " + nums[1] +
                        " Получил в результате число: " + digit);
                Thread.sleep(1000);
            }
        } catch (InterruptedException | IOException e) {
            System.out.println("error");
        }
    }
}
0
 Аватар для Goongala
1022 / 562 / 185
Регистрация: 18.08.2013
Сообщений: 2,027
Записей в блоге: 2
26.10.2019, 11:05
Лучший ответ Сообщение было отмечено W014ara как решение

Решение

В общем, я потратил достаточно много времени, но так и не смог сделать ничего умного, поэтому пришлось делать то, что работает. При каждой итерации второй поток с самого начала читает файл. Стрёмненько, но иначе никак сделать у меня не вышло
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
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
 
public class Test {
    public static void main(String[] args) {
        First_Thread first_thread = new First_Thread();
        Second_Thread second_thread = new Second_Thread();
        Third_Thread third_thread = new Third_Thread();
 
        new Thread(first_thread).start();
        new Thread(second_thread).start();
        //new Thread(third_thread).start();
    }
}
 
class First_Thread implements Runnable {
    @Override
    public void run() {
        Random rand = ThreadLocalRandom.current();
        String path = Test.class.getResource("text").getPath();
 
        try (PrintWriter pw = new PrintWriter(new FileWriter(path, true), true)) {
            while (true) {
                int digit = rand.nextInt(100);
                System.out.println(digit);
                pw.println(digit);
                Thread.sleep(1000);
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}
 
class Second_Thread implements Runnable {
    @Override
    public void run() {
        String path = Test.class.getResource("text1").getPath();
        int[] nums = new int[2];
        int index = 0;
 
        try (PrintWriter pw = new PrintWriter(new FileWriter(path, true), true)) {
            while (true) {
                try (Scanner in = new Scanner(Test.class.getResourceAsStream("text"), "UTF-8")) {
                    while (in.hasNextInt()) {
                        nums[index++] = in.nextInt();
                        if (index == 2) {
                            index = 0;
                        }
                    }
                    String digit = Integer.toString(nums[0] + nums[1]);
                    System.out.println("Второй поток сложил числа: " + nums[0] + " и " + nums[1] +
                            " - получил в результате число: " + digit);
                    pw.println(digit);
                }
                Thread.sleep(1000);
            }
        } catch (InterruptedException | IOException e) {
            System.out.println("error");
        }
    }
}
1
1 / 1 / 1
Регистрация: 11.07.2018
Сообщений: 96
26.10.2019, 14:06  [ТС]
Gungala

Спасибо большое, да, отрабатывает именно так, как нужно.

Добавлено через 30 минут
Gungala

Единственное, хотел дополнительно спросить, как можно будет синхронизировать мои три потока?
Чтобы они отрабатывали именно в порядке 1 2 3, а не, например 1 3 2?
0
 Аватар для Goongala
1022 / 562 / 185
Регистрация: 18.08.2013
Сообщений: 2,027
Записей в блоге: 2
26.10.2019, 15:29
Не совсем понимаю, зачем использовать многопоточность, если нужно последовательное выполнение. Не знаю, если честно, я сам в этом деле почти не имею опыта. Возможно, BlockingQueue подошла бы, погугли
0
1 / 1 / 1
Регистрация: 11.07.2018
Сообщений: 96
26.10.2019, 16:16  [ТС]
Понимаю, что можно обойтись без многопоточности, но так поставили задание. Спасибо за помощь, еще раз!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.10.2019, 16:16
Помогаю со студенческими работами здесь

Многопоточность и работа с прокси
здравствуйте, решил написать простенькую программу с потоками и работай через прокси(HTTP/S, SOCKS4/5) как это сделать проще всего?...

Многопоточность, не правильная работа с мютекосом. Что не так?
Добрый. Хочу чтобы разрешение (permission) устанавливалось только один раз каким-либо потоком, а затем забиралось каким-либо другим. ...

Работа с файлами(Запись,чтение,работа с данными)
Здравствуйте, никак не могу осилить файлы... Для начала вот само задание: В справочной автовокзала хранится расписание движения автобусов....

Лабораторная работа №5. Работа с файлами и алгоритмы сортировки
1. Написать функцию Load для считывания из текстового файла (например, Workers.txt) информации о работниках и заработной плате. В первой...

Работа с файлами, чтение/работа со строкой
Доброго времени суток. Начал работать с C++ Builder 6. Есть текстовый файл .txt с различными строками, как можно производить...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
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
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru