diff --git a/src/com/walking/lesson60_thread/task1/Main.java b/src/com/walking/lesson60_thread/task1/Main.java index 8f110b749..19132ae81 100644 --- a/src/com/walking/lesson60_thread/task1/Main.java +++ b/src/com/walking/lesson60_thread/task1/Main.java @@ -1,10 +1,40 @@ package com.walking.lesson60_thread.task1; +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.FormatStyle; +import java.time.temporal.ChronoUnit; + /** * Напишите программу, которая пишет в консоль текущее время каждый две секунды, * пока программа запущена. */ public class Main { - public static void main(String[] args) { + public static void main(String[] args) throws InterruptedException { + Duration twoSeconds = Duration.of(2, ChronoUnit.SECONDS); + + DateTimeFormatter mediumTimeFormatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM); + + Thread timePrinter = new Thread(printTimeCyclical(twoSeconds, mediumTimeFormatter), "timePrinter"); + + timePrinter.start(); + } + + public static Runnable printTimeCyclical(Duration duration, DateTimeFormatter formatter) { + return () -> { + while (!Thread.currentThread() + .isInterrupted()) { + System.out.println(LocalDateTime.now() + .format(formatter)); + + try { + Thread.sleep(duration); + } catch (InterruptedException e) { + Thread.currentThread() + .interrupt(); + } + } + }; } } \ No newline at end of file diff --git a/src/com/walking/lesson60_thread/task2/Main.java b/src/com/walking/lesson60_thread/task2/Main.java index 6d944884d..a57d76b3b 100644 --- a/src/com/walking/lesson60_thread/task2/Main.java +++ b/src/com/walking/lesson60_thread/task2/Main.java @@ -1,5 +1,14 @@ package com.walking.lesson60_thread.task2; +import com.walking.lesson60_thread.task2.model.ExtremeMultiThreadTableFiller; +import com.walking.lesson60_thread.task2.model.MultiThreadTableFiller; +import com.walking.lesson60_thread.task2.model.SingleThreadTableFiller; +import com.walking.lesson60_thread.task2.model.TableFiller; + +import java.time.Duration; +import java.time.LocalTime; +import java.util.Random; + /** * Опишите интерфейс, декларирующий метод, заполняющий двумерный массив заданных размеров * случайными числами от 1 до 10. @@ -11,6 +20,30 @@ * динамически-определяемым в зависимости от размера массива*. */ public class Main { - public static void main(String[] args) { + public static void main(String[] args) throws InterruptedException { + LocalTime startTime = LocalTime.now(); + + Random random = new Random(); + int[][] numbers = new int[10][10_000_000]; + TableFiller tableFiller = new MultiThreadTableFiller(); + + tableFiller.fillTable(numbers, () -> random.nextInt(1, 11)); + +// print2DArray(numbers); + + LocalTime endTime = LocalTime.now(); + + System.out.printf("Overall time = %s\n".formatted(Duration.between(startTime, endTime) + .toMillis())); + } + + public static void print2DArray(int[][] array) { + for (int[] row : array) { + for (int column : row) { + System.out.printf("[%s]".formatted(column)); + } + + System.out.println(); + } } } \ No newline at end of file diff --git a/src/com/walking/lesson60_thread/task2/model/ExtremeMultiThreadTableFiller.java b/src/com/walking/lesson60_thread/task2/model/ExtremeMultiThreadTableFiller.java new file mode 100644 index 000000000..6b115d2fa --- /dev/null +++ b/src/com/walking/lesson60_thread/task2/model/ExtremeMultiThreadTableFiller.java @@ -0,0 +1,83 @@ +package com.walking.lesson60_thread.task2.model; + +import java.util.function.IntSupplier; + +public class ExtremeMultiThreadTableFiller implements TableFiller { + private static final int MAX_ELEMENTS_IN_THREAD = 500_000_000; + + @Override + public void fillTable(int[][] table, IntSupplier value) throws InterruptedException { + Thread tableFiller = new Thread(tableFillingProcess(table, value), "tableFiller"); + + tableFiller.start(); + + tableFiller.join(); + } + + private Runnable tableFillingProcess(int[][] table, IntSupplier value) throws InterruptedException { + return () -> { + /* List threadList = new ArrayList<>(table.length);*/ + + for (int[] row : table) { + int partCount = Math.max(1, row.length / MAX_ELEMENTS_IN_THREAD); + + Thread rowFiller = new Thread(() -> { + try { + fillRow(row, partCount, value); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }, "rowFiller"); + + /* threadList.add(rowFiller);*/ + + rowFiller.start(); + } + + /*for (Thread thread : threadList) { + try { + thread.join(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + }*/ + }; + } + + private void fillRow(int[] row, int partCount, IntSupplier value) throws InterruptedException { + /*List threadList = new ArrayList<>(partCount);*/ + + int offset = row.length / partCount; + int startIndex = 0; + int endIndex = offset; + + for (int i = 0; i < partCount; i++) { + fillRowPart(row, startIndex, endIndex, value/*, threadList*/); + + startIndex += offset; + endIndex += offset; + } + + /*for (Thread thread : threadList) { + thread.join(); + }*/ + } + + private void fillRowPart(int[] row, int startInclusive, int endExclusive, + IntSupplier value/*, List threadList*/) throws InterruptedException { + Thread partRowFiller = new Thread(partRowFillingProcess(row, startInclusive, endExclusive, value), + "partRowFiller"); + + /*threadList.add(partRowFiller);*/ + + partRowFiller.start(); + } + + private Runnable partRowFillingProcess(int[] row, int startInclusive, int endExclusive, IntSupplier value) { + return () -> { + for (int i = startInclusive; i < endExclusive; i++) { + row[i] = value.getAsInt(); + } + }; + } +} \ No newline at end of file diff --git a/src/com/walking/lesson60_thread/task2/model/MultiThreadTableFiller.java b/src/com/walking/lesson60_thread/task2/model/MultiThreadTableFiller.java new file mode 100644 index 000000000..f48be040c --- /dev/null +++ b/src/com/walking/lesson60_thread/task2/model/MultiThreadTableFiller.java @@ -0,0 +1,42 @@ +package com.walking.lesson60_thread.task2.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.IntSupplier; + +public class MultiThreadTableFiller implements TableFiller { + @Override + public void fillTable(int[][] table, IntSupplier value) throws InterruptedException { + Thread tableFiller = new Thread(tableFillingProcess(table, value), "tableFiller"); + + tableFiller.start(); + + tableFiller.join(); + } + + private Runnable tableFillingProcess(int[][] table, IntSupplier value) { + return () -> { + List threadList = new ArrayList<>(table.length); + + for (int[] row : table) { + Thread rowFiller = new Thread(() -> { + Arrays.setAll(row, x -> value.getAsInt()); + + }, "rowFiller"); + + threadList.add(rowFiller); + + rowFiller.start(); + } + + for (Thread thread : threadList) { + try { + thread.join(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + }; + } +} diff --git a/src/com/walking/lesson60_thread/task2/model/SingleThreadTableFiller.java b/src/com/walking/lesson60_thread/task2/model/SingleThreadTableFiller.java new file mode 100644 index 000000000..bfb897228 --- /dev/null +++ b/src/com/walking/lesson60_thread/task2/model/SingleThreadTableFiller.java @@ -0,0 +1,23 @@ +package com.walking.lesson60_thread.task2.model; + +import java.util.Arrays; +import java.util.function.IntSupplier; + +public class SingleThreadTableFiller implements TableFiller { + @Override + public void fillTable(int[][] table, IntSupplier value) throws InterruptedException { + Thread tableFiller = new Thread(tableFillingProcess(table, value), "tableFiller"); + + tableFiller.start(); + + tableFiller.join(); + } + + private Runnable tableFillingProcess(int[][] table, IntSupplier value) { + return () -> { + for (int[] row : table) { + Arrays.setAll(row, x -> value.getAsInt()); + } + }; + } +} diff --git a/src/com/walking/lesson60_thread/task2/model/TableFiller.java b/src/com/walking/lesson60_thread/task2/model/TableFiller.java new file mode 100644 index 000000000..f07ffac88 --- /dev/null +++ b/src/com/walking/lesson60_thread/task2/model/TableFiller.java @@ -0,0 +1,7 @@ +package com.walking.lesson60_thread.task2.model; + +import java.util.function.IntSupplier; + +public interface TableFiller { + void fillTable(int[][] table, IntSupplier value) throws InterruptedException; +} diff --git a/src/com/walking/lesson60_thread/task3/Main.java b/src/com/walking/lesson60_thread/task3/Main.java index ade44a2e7..566773288 100644 --- a/src/com/walking/lesson60_thread/task3/Main.java +++ b/src/com/walking/lesson60_thread/task3/Main.java @@ -1,5 +1,9 @@ package com.walking.lesson60_thread.task3; +import com.walking.lesson60_thread.task3.model.FunctionExecutor; + +import java.util.Random; + /** * Уже на текущем этапе мы можем распараллелить какие-то действия с помощью многопоточности. * Но иногда требуется выполнить определенную операцию в другом потоке и получить ее результат. @@ -10,6 +14,18 @@ * Его метод имеет возвращаемое значение. */ public class Main { - public static void main(String[] args) { + public static void main(String[] args) throws InterruptedException { + FunctionExecutor lengthCalculator = new FunctionExecutor<>("Test_string", String::length); + + System.out.println(lengthCalculator.call()); + + FunctionExecutor toUpperCase = new FunctionExecutor<>("Test_string", String::toUpperCase); + + System.out.println(toUpperCase.call()); + + FunctionExecutor oddOrEvenPrinter = new FunctionExecutor<>(new Random().nextInt(10), + i -> i % 2 == 0 ? "%s is even".formatted(i) : "%s is odd".formatted(i)); + + System.out.println(oddOrEvenPrinter.call()); } } \ No newline at end of file diff --git a/src/com/walking/lesson60_thread/task3/model/FunctionExecutor.java b/src/com/walking/lesson60_thread/task3/model/FunctionExecutor.java new file mode 100644 index 000000000..51f17eba9 --- /dev/null +++ b/src/com/walking/lesson60_thread/task3/model/FunctionExecutor.java @@ -0,0 +1,26 @@ +package com.walking.lesson60_thread.task3.model; + +import java.util.concurrent.Callable; +import java.util.function.Function; + +public class FunctionExecutor implements Callable { + T value; + Function function; + R result; + + public FunctionExecutor(T value, Function function) { + this.value = value; + this.function = function; + } + + @Override + public R call() throws InterruptedException { + Thread thread = new Thread(() -> result = function.apply(value), "thread"); + + thread.start(); + + thread.join(); + + return result; + } +} diff --git a/src/com/walking/lesson60_thread/task4/Main.java b/src/com/walking/lesson60_thread/task4/Main.java index abfa61f8a..e30434cdb 100644 --- a/src/com/walking/lesson60_thread/task4/Main.java +++ b/src/com/walking/lesson60_thread/task4/Main.java @@ -1,9 +1,25 @@ package com.walking.lesson60_thread.task4; +import com.walking.lesson60_thread.task4.model.FunctionExecutor; + +import java.util.Random; + /** * Решите Задачу 3, не используя Thread.join(). */ public class Main { - public static void main(String[] args) { + public static void main(String[] args) throws InterruptedException { + FunctionExecutor lengthCalculator = new FunctionExecutor<>("Test_string", String::length); + + System.out.println(lengthCalculator.call()); + + FunctionExecutor toUpperCase = new FunctionExecutor<>("Test_string", String::toUpperCase); + + System.out.println(toUpperCase.call()); + + FunctionExecutor oddOrEvenPrinter = new FunctionExecutor<>(new Random().nextInt(10), + i -> i % 2 == 0 ? "%s is even".formatted(i) : "%s is odd".formatted(i)); + + System.out.println(oddOrEvenPrinter.call()); } } \ No newline at end of file diff --git a/src/com/walking/lesson60_thread/task4/model/FunctionExecutor.java b/src/com/walking/lesson60_thread/task4/model/FunctionExecutor.java new file mode 100644 index 000000000..cc179ca14 --- /dev/null +++ b/src/com/walking/lesson60_thread/task4/model/FunctionExecutor.java @@ -0,0 +1,30 @@ +package com.walking.lesson60_thread.task4.model; + +import java.util.concurrent.Callable; +import java.util.function.Function; + +public class FunctionExecutor implements Callable { + T value; + Function function; + R result; + + public FunctionExecutor(T value, Function function) { + this.value = value; + this.function = function; + } + + @Override + public R call() throws InterruptedException { + Thread thread = new Thread(() -> result = function.apply(value), "thread"); + + thread.start(); + + while (true) { + if (!thread.isAlive()) { + break; + } + } + + return result; + } +}