Java: Как правильно синхронизировать потоки?
Всем привет. У меня не получается синхронизировать потоки, из-за чего происходят траблы с консолью (по крайней мере, я так думаю, что всё дело в синхронизации потоков) — она выводит:
Содержимое файла: 6 8 6 9 7 8 8 6 0 6 2 9 8 0 4 7 3 0 5 4
Количество нечётных чисел: 6
Количество чётных чисел: 11
Нечётные числа: Чётные числа: 9 7 9 7 3 5
6 8 6 8 8 6 6 2 8 4 4
Хотя должна выводить что-то вроде этого:
Содержимое файла: 1 9 4 5 0 4 9 8 7 3 3 1 5 4 7 4 4 3 9 8
Количество чётных чисел: 7
Чётные числа: 4 4 8 4 4 4 8
Количество нечётных чисел: 12
Нечётные числа: 1 9 5 9 7 3 3 1 5 7 3 9
Один поток ищет чётные числа, а второй — нечётные. Есть также и третий поток, который заполняет массив случайными числами, после чего, остальные два потока стартуют. Пример содержимого текстовика: 1 9 4 5 0 4 9 8 7 3 3 1 5 4 7 4 4 3 9 8.
package com.company;
import java.io.*;
import java.util.Scanner;
public class Main
{
static int My_Array[]; static String path1; static String file_name1;
static void printResult1(File file) throws FileNotFoundException
{
Scanner scanner = new Scanner(file);
String line = scanner.nextLine();
String[] numbers = line.split(" ");
System.out.print("Чётные числа:\t");
for (String number : numbers) { if (Integer.parseInt(number) != 0 && Integer.parseInt(number) % 2 == 0) { System.out.print(number + " "); } }
}
static void printResult2(File file) throws FileNotFoundException
{
Scanner scanner = new Scanner(file);
String line = scanner.nextLine();
String[] numbers = line.split(" ");
System.out.print("Нечётные числа:\t");
for (String number : numbers) { if (Integer.parseInt(number) != 0 && Integer.parseInt(number) % 2 != 0) { System.out.print(number + " "); } }
}
static class My_random_numbers_Thread extends Thread
{
public synchronized void run()
{
// Сгенерировать массив из 20и рандомных чисел диапазоном 0-10
My_Array = new int[20]; for (int i = 0; i < My_Array.length; i++) { My_Array[i] = (int)(Math.random()*11); }
// Перезаписать данные файла и записать в файл массив рандомных чисел
int new_data[] = My_Array;
BufferedWriter outputWriter = null;
try { outputWriter = new BufferedWriter(new FileWriter(file_name1)); }
catch (IOException e) { e.printStackTrace(); }
for (int i = 0; i < new_data.length; i++)
{
try { outputWriter.write(new_data[i] + " "); }
catch (IOException e) { e.printStackTrace(); }
}
try { outputWriter.flush(); }
catch (IOException e) { e.printStackTrace(); }
try { outputWriter.close(); }
catch (IOException e) { e.printStackTrace(); }
System.out.println("Файл перезаписан и прочитан!");
}
}
static class My_search_for_even_numbers_Thread extends Thread
{
public void run()
{
// Поиск чётных чисел
int count1 = 0;
try (Scanner sc = new Scanner(new File(path1)))
{ while (sc.hasNextInt()) { int i = sc.nextInt(); if (i % 2 == 0 && i != 0) { count1++; } } }
catch (IOException ex) { ex.printStackTrace(); }
System.out.println("Количество чётных чисел:\t" + count1);
File file = new File(path1);
try { printResult1(file);System.out.println(); }
catch (FileNotFoundException e) { e.printStackTrace(); }}
}
static class My_search_for_odd_numbers_Thread extends Thread
{
public void run()
{
// Поиск нечётных чисел
int count2 = 0;
try (Scanner sc = new Scanner(new File(path1)))
{ while (sc.hasNextInt()) { int i = sc.nextInt(); if (i % 2 != 0 && i != 0) { count2++; } } }
catch (IOException ex) { ex.printStackTrace(); }
System.out.println("Количество нечётных чисел:\t" + count2);
File file = new File(path1);
try { printResult2(file);System.out.println(); }
catch (FileNotFoundException e) { e.printStackTrace(); }
}
}
public static void main(String[] args) throws InterruptedException
{
// Указать путь+файл(-.txt) и проверить на предмет наличия файла
Scanner scanner1 = new Scanner(System.in);
System.out.print("Введи путь: "); /*C:/Users/Test_User/IdeaProjects/Test_Console1/Test_text.txt*/
path1 = scanner1.nextLine();
file_name1 = path1;
File file1 = new File(file_name1); if (file1.exists()) { System.out.println("Файл есть!"); } else { System.out.println("Файла нет!"); }
// Thread: Сгенерировать рандомные числа
new My_random_numbers_Thread().start();
Thread.sleep(500);
// Прочитать и вывести данные из файла
try(FileInputStream fis1 = new FileInputStream(file_name1))
{
byte[] buffer = new byte[fis1.available()];
fis1.read(buffer);
String file_data1 = new String(buffer);
System.out.println("\nСодержимое файла: " + file_data1);
int i = -1;
while ((i=fis1.read()) != -1) { System.out.print((char)i); }
}
catch (IOException ex) { System.out.println(ex.getMessage()); }
Thread.sleep(500);
// Thread: Чётные числа
new My_search_for_even_numbers_Thread().start();
// Thread: Нечётные числа
new My_search_for_odd_numbers_Thread().start();
Thread.sleep(500);
}
}