Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

LR1.Tyutterin_Yakov_Z1411-3

.pdf
Скачиваний:
0
Добавлен:
29.04.2024
Размер:
473.2 Кб
Скачать

МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ федеральное государственное автономное образовательное учреждение высшего образования

«САНКТ-ПЕТЕРБУРГСКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ АЭРОКОСМИЧЕСКОГО ПРИБОРОСТРОЕНИЯ»

ИНСТИТУТ НЕПРЕРЫВНОГО И ДИСТАНЦИОННОГО ОБРАЗОВАНИЯ

КАФЕДРА ПРИКЛАДНОЙ ИНФОРМАТИКИ

ОЦЕНКА

ПРЕПОДАВАТЕЛЬ

Канд. техн. наук

 

С. А. Чернышев

должность, уч. степень, звание

подпись, дата

инициалы, фамилия

ОТЧЕТ О ЛАБОРАТОРНОЙ РАБОТЕ №1

Потоки

по дисциплине: Технологии программирования

РАБОТУ ВЫПОЛНИЛ

 

 

 

 

 

СТУДЕНТ гр. №

Z1411

 

 

Я. Н. Тюттерин

 

 

 

 

 

 

 

номер группы

подпись, дата

 

инициалы, фамилия

Студенческий билет №

2022/4886

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Санкт-Петербург 2024

Лабораторная работа № 1. Потоки

Цель работы: познакомиться с основными способами работы с потоками.

Вариант 18.

Задание 1: Напишите программу, которая осуществляет чтение данных из файла в одном потоке и запись этих данных в другом потоке в файл. Названия файлов должны отличаться.

import java.io.*;

import java.nio.charset.StandardCharsets; import java.util.concurrent.*;

import java.util.concurrent.atomic.AtomicInteger;

public class Main {

public static void main(String[] args) throws InterruptedException { new Main().run();

}

private void run() throws InterruptedException { String fileRead = "resources/text.txt"; //Количество строк в файле

AtomicInteger count = new AtomicInteger(countLines(fileRead)); //Счетчик для сигнала о корректном выполнении потоков

final CountDownLatch latch = new CountDownLatch(count.get());

final ExecutorService executorService = Executors.newFixedThreadPool(2);

//Потокобезопасная очередь

final ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();

//Поток чтения

Runnable reader = () -> {

try (BufferedReader br = new BufferedReader(new FileReader(fileRead, StandardCharsets.UTF_8))) {

while (br.ready()) {

//Чтобы избежать пустой строки в конце файла if (count.decrementAndGet() != 0) {

queue.add(br.readLine().concat("\n")); } else {

queue.add(br.readLine());

}

}

} catch (IOException ex) {

throw new RuntimeException("Что-то пошло не так", ex);

}

};

final String fileOut = "resources/text-out.txt";

//Поток записи

Runnable writer = () -> {

try (BufferedWriter bw = new BufferedWriter(new FileWriter(fileOut, StandardCharsets.UTF_8))) {

final int batchSize = 50; int countLine = 0;

do {

if (!queue.isEmpty()) { bw.append(queue.poll());

if (batchSize == ++countLine) { bw.flush();

countLine = 0;

}

latch.countDown();

}

//Проверяем, что счетчик не стал равен 0, что сигнализирует об

окончании файла

} while (latch.getCount() != 0);

if (countLine != 0) { bw.flush();

}

} catch (IOException ex) {

throw new RuntimeException("Что-то пошло не так", ex);

}

};

//Запуск потока чтения

executorService.submit(reader); System.out.println("Hello"); //Запуск потока записи executorService.submit(writer); System.out.println("Hello");

latch.await();

executorService.shutdown();

}

//Метод подсчета строк в файле

private static int countLines(String filename) {

try (InputStream is = new BufferedInputStream(new FileInputStream(filename)))

{

byte[] c = new byte[1024];

int readChars = is.read(c); if (readChars == -1) {

// bail out if nothing to read return 0;

}

// make it easy for the optimizer to tune this loop int count = 0;

while (readChars == 1024) {

for (int i = 0; i < 1024; ) { if (c[i++] == '\n') {

++count;

}

}

readChars = is.read(c);

}

// count remaining characters while (readChars != -1) {

for (int i = 0; i < readChars; ++i) { if (c[i] == '\n') {

++count;

}

}

readChars = is.read(c);

}

return count == 0 ? 1 : count + 1; } catch (IOException ex) {

throw new RuntimeException(ex);

}

}

}

Наполнение файла имеет подобный вид:

Результат выполнения:

Задание 8: Напишите приложение для нахождения с использованием трех потоков значения по задаваемому диапазону элементов списка. Потоки должны полностью перекрывать длину списка.

import java.util.*;

import java.util.concurrent.*; import java.util.stream.Stream;

public class Main {

public static void main(String[] args) throws InterruptedException { Scanner scanner = new Scanner(System.in); System.out.println("Какую подстроку ищем?");

String findSubLine = scanner.next(); System.out.println("С какого индекса ищем"); int start = scanner.nextInt(); System.out.println("По какой индекс ищем"); int end = scanner.nextInt();

//Генерируем список строк в количестве end + 1(В будущем можно заменить на другой источник данных)

final List<String> data = Stream.generate(() -> UUID.randomUUID().toString().concat(UUID.randomUUID().toString())).limit(end + 1).toList();

new Main().run(findSubLine, start, end, data);

}

private void run(String findSubLine, int start, int end, List<String> data) throws InterruptedException {

final ExecutorService executorService = Executors.newFixedThreadPool(3); //Общее количество значений, которое требуется обработать

int count = end - start;

//"Счетчик", равенство = 0 будет ожидаться для корректного завершения выполнения

final CountDownLatch latch = new CountDownLatch(count);

final ConcurrentMap<Integer, String> strByIndex = new ConcurrentHashMap<>();

//Получаем размер партиции final int partition = count / 3;

final List<Runnable> tasks = new ArrayList<>(3); for (; start < end; start += (partition + 1)) {

//Вычисляем значение окончания партиции(учитывается, что на равные части деление может быть не возможно)

int endInclusive = Math.min(start + partition, end); final int finalStart = start;

//Заполняем список потоков tasks.add(() -> {

for (int i = finalStart; i <= endInclusive; i++) { final String line = data.get(i);

if (line.contains(findSubLine)) { strByIndex.put(i, line);

}

latch.countDown();

}

});

}

//Запускаем все созданные потоки

tasks.forEach(executorService::submit);

//Ждем, пока счетчик не станет 0

latch.await();

executorService.shutdown();

System.out.println(strByIndex);

}

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]