Thread file reading java

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

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

Имеется 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

Исходный код основного класса

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 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("Не удалось открыть файл!"); } } }
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() { ListInteger> 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()); } } }

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

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

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

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

Чувак, зачем ты у них sleep вызываешь? Их надо просто запустить и забыть про них

Добавлено через 1 минуту
И оборачивай их в Thread

sleep вызывается, чтобы в файл записывались значения через каждую 1 с., а не через каждые микросекунды. Что значит оборачивать их в Thread? Разве Runnable не производит этого?

ЦитатаСообщение от W014ara Посмотреть сообщение

Нет. Нельзя вручную вызывать метод run у Runnable, надо оборачивать в Thread. Цикл чтения и записи сделай внутри Runnable и если надо, то добавь туда sleep()

Эксперт Java

ЦитатаСообщение от Gungala Посмотреть сообщение

First_Thread first_thread = new First_Thread(); new Thread(first_thread).start();

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 строки в файле, при этом не закрывая его?

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(); } }

Компилятор кричит на ошибку в строчке.

try (Scanner in = new Scanner(Test.class.getResourceAsStream("text.txt"), "UTF-8"))

Не особо понимаю, файл вроде бы существует и первый поток записывает в него данные, но вот 2 поток уже кричит.

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

Основной класс программы

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(); } }
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 поток

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 поток соответственно:

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"); } } }

Лучший ответ

Сообщение было отмечено W014ara как решение

Решение

В общем, я потратил достаточно много времени, но так и не смог сделать ничего умного, поэтому пришлось делать то, что работает. При каждой итерации второй поток с самого начала читает файл. Стрёмненько, но иначе никак сделать у меня не вышло

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"); } } }

Источник

Читайте также:  Dynamic Scaling Example
Оцените статью