From 51a24cf6db1bab16f57841b9d67a2965fc799171 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jan=20Ko=C5=BEusznik?= <jan@kozusznik.cz>
Date: Wed, 24 Mar 2021 14:12:12 +0100
Subject: [PATCH] solution

---
 .../koz01/java2/lab07/ComplicatedProcess.java | 49 ++++++++++
 .../java/koz01/java2/lab07/TestThread.java    | 89 +++++++++++++++++++
 2 files changed, 138 insertions(+)
 create mode 100644 src/test/java/koz01/java2/lab07/ComplicatedProcess.java
 create mode 100644 src/test/java/koz01/java2/lab07/TestThread.java

diff --git a/src/test/java/koz01/java2/lab07/ComplicatedProcess.java b/src/test/java/koz01/java2/lab07/ComplicatedProcess.java
new file mode 100644
index 0000000..4e477d4
--- /dev/null
+++ b/src/test/java/koz01/java2/lab07/ComplicatedProcess.java
@@ -0,0 +1,49 @@
+package koz01.java2.lab07;
+
+import java.math.BigInteger;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+import lombok.extern.log4j.Log4j2;
+
+@Log4j2
+public class ComplicatedProcess {
+
+	private Random rnd = new Random();
+
+	public void doNop(Consumer<Long> durationConsumer) {
+		long start = System.currentTimeMillis();
+		try {
+			TimeUnit.MILLISECONDS.sleep(rnd.nextInt(3001) + 2000);
+		}
+		catch (InterruptedException exc) {
+			log.error("sleep", exc);
+		}
+
+		durationConsumer.accept(System.currentTimeMillis() - start);
+	}
+
+	public Long doNopReturnDuration() {
+		long start = System.currentTimeMillis();
+		try {
+			TimeUnit.MILLISECONDS.sleep(rnd.nextInt(3001) + 2000);
+		}
+		catch (InterruptedException exc) {
+			log.error("sleep", exc);
+		}
+
+		return System.currentTimeMillis() - start;
+	}
+
+	public Long doComputeFactorial() {
+		long start = System.currentTimeMillis();
+
+		BigInteger result = BigInteger.ONE;
+		for (int i = 2; i <= 50000; i++) {
+			result = result.multiply(BigInteger.valueOf(i));
+		}
+		return System.currentTimeMillis() - start;
+	}
+
+}
diff --git a/src/test/java/koz01/java2/lab07/TestThread.java b/src/test/java/koz01/java2/lab07/TestThread.java
new file mode 100644
index 0000000..b42c32a
--- /dev/null
+++ b/src/test/java/koz01/java2/lab07/TestThread.java
@@ -0,0 +1,89 @@
+
+package koz01.java2.lab07;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+
+import org.junit.jupiter.api.Test;
+
+import lombok.extern.log4j.Log4j2;
+
+@Log4j2
+public class TestThread {
+
+	@Test
+	public void testThreads() {
+		final ComplicatedProcess cp = new ComplicatedProcess();
+		Collection<Thread> threads = new LinkedList<>();
+		Collection<Long> durations = new LinkedList<>();
+		long start = System.currentTimeMillis();
+		for (int i = 0; i < 10; i++) {
+			final int threadNu = i;
+			Thread t = new Thread() {
+
+				@Override
+				public void run() {
+					cp.doNop(l -> durations.add(l));
+				};
+			};
+			t.start();
+			threads.add(t);
+		}
+		threads.stream().forEach(t -> {
+			try {
+				t.join();
+			}
+			catch (InterruptedException exc) {
+				log.error("join", t);
+			}
+		});
+		long totalDuration = System.currentTimeMillis() - start;
+		long maxDuration = durations.stream().mapToLong(l -> l).max().getAsLong();
+		log.info("duration: {}/{} ms", maxDuration, totalDuration);
+	}
+
+	@Test
+	public void testExecutors() {
+		int threads = Runtime.getRuntime().availableProcessors();
+		ExecutorService executorService = Executors.newFixedThreadPool(threads);
+		log.info("Threads: {}", threads);
+		final ComplicatedProcess cp = new ComplicatedProcess();
+		runExecutors(executorService, cp);
+		executorService.shutdown();
+	}
+
+	private void runExecutors(ExecutorService executorService,
+		final ComplicatedProcess cp)
+	{
+
+		Collection<Future<Long>> executions = new LinkedList<>();
+		long start = System.currentTimeMillis();
+		for (int i = 0; i < 10; i++) {
+			Future<Long> execution = executorService.submit(cp::doComputeFactorial);
+			executions.add(execution);
+		}
+		Collection<Long> durations = executions.stream().map(this::getValue)
+			.collect(Collectors.toList());
+		long totalDuration = System.currentTimeMillis() - start;
+		long maxDuration = durations.stream().mapToLong(l -> l).max().getAsLong();
+		log.info("duration: {}/{} ms", maxDuration, totalDuration);
+	}
+
+	private Long getValue(Future<Long> f) {
+		{
+			try {
+				return f.get();
+			}
+			catch (InterruptedException | ExecutionException exc) {
+				log.error("get", exc);
+				return Long.valueOf(-1);
+			}
+		}
+
+	}
+}
-- 
GitLab