From 4c18bc9f05a8b3c5194cb1493195aab3f8f00045 Mon Sep 17 00:00:00 2001 From: kshokh <128833441+kshokh@users.noreply.github.com> Date: Mon, 20 Oct 2025 22:04:52 -0400 Subject: [PATCH 1/2] Lesson 11 --- lessons/.gradle/file-system.probe | Bin 8 -> 8 bytes lessons/build.gradle | 2 ++ .../src/main/java/lessons/lesson11/App.java | 17 ++++++++++ .../java/lessons/lesson11/MessageQueue.java | 11 +++++++ .../main/java/lessons/lesson11/Publisher.java | 30 ++++++++++++++++++ .../java/lessons/lesson11/Subscriber.java | 24 ++++++++++++++ 6 files changed, 84 insertions(+) create mode 100644 lessons/src/main/java/lessons/lesson11/App.java create mode 100644 lessons/src/main/java/lessons/lesson11/MessageQueue.java create mode 100644 lessons/src/main/java/lessons/lesson11/Publisher.java create mode 100644 lessons/src/main/java/lessons/lesson11/Subscriber.java diff --git a/lessons/.gradle/file-system.probe b/lessons/.gradle/file-system.probe index f55ab291748e983b9c9ad0567df044c245d6f3ed..b4d29de176c776c0c93c28e8773e5db23f79a9d2 100644 GIT binary patch literal 8 PcmZQzV4THLeCh=N2K55P literal 8 PcmZQzV4TGyE3OLw1IhsZ diff --git a/lessons/build.gradle b/lessons/build.gradle index 34291ce..ec6799f 100644 --- a/lessons/build.gradle +++ b/lessons/build.gradle @@ -12,6 +12,8 @@ repositories { dependencies { testImplementation platform('org.junit:junit-bom:5.10.0') testImplementation 'org.junit.jupiter:junit-jupiter' + compileOnly 'org.projectlombok:lombok:1.18.34' + annotationProcessor 'org.projectlombok:lombok:1.18.34' } test { diff --git a/lessons/src/main/java/lessons/lesson11/App.java b/lessons/src/main/java/lessons/lesson11/App.java new file mode 100644 index 0000000..3249e9c --- /dev/null +++ b/lessons/src/main/java/lessons/lesson11/App.java @@ -0,0 +1,17 @@ +package lessons.lesson11; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class App { + public static void main(String[] args) { + MessageQueue queue = new MessageQueue(); + + ExecutorService executor = Executors.newFixedThreadPool(2); + + executor.submit(new Publisher(queue)); + executor.submit(new Subscriber(queue)); + + executor.shutdown(); + } +} diff --git a/lessons/src/main/java/lessons/lesson11/MessageQueue.java b/lessons/src/main/java/lessons/lesson11/MessageQueue.java new file mode 100644 index 0000000..1906a27 --- /dev/null +++ b/lessons/src/main/java/lessons/lesson11/MessageQueue.java @@ -0,0 +1,11 @@ +package lessons.lesson11; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +import lombok.Getter; + +@Getter +public class MessageQueue { + private final BlockingQueue queue = new LinkedBlockingQueue<>(); +} diff --git a/lessons/src/main/java/lessons/lesson11/Publisher.java b/lessons/src/main/java/lessons/lesson11/Publisher.java new file mode 100644 index 0000000..98b5612 --- /dev/null +++ b/lessons/src/main/java/lessons/lesson11/Publisher.java @@ -0,0 +1,30 @@ +package lessons.lesson11; + +import lombok.RequiredArgsConstructor; + +import java.util.Scanner; + +@RequiredArgsConstructor +public class Publisher implements Runnable { + private final MessageQueue queue; + private volatile boolean running = true; + + @Override + public void run() { + try (Scanner scanner = new Scanner(System.in)) { + System.out.println("Words to publish ('exit' to quit):"); + while (running) { + String input = scanner.nextLine(); + if ("exit".equalsIgnoreCase(input.trim())) { + running = false; + queue.getQueue().put("exit"); + } else { + queue.getQueue().put(input); + } + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.out.println("Publisher interrupted."); + } + } +} diff --git a/lessons/src/main/java/lessons/lesson11/Subscriber.java b/lessons/src/main/java/lessons/lesson11/Subscriber.java new file mode 100644 index 0000000..f7994e1 --- /dev/null +++ b/lessons/src/main/java/lessons/lesson11/Subscriber.java @@ -0,0 +1,24 @@ +package lessons.lesson11; + +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class Subscriber implements Runnable { + private final MessageQueue queue; + + @Override + public void run() { + try { + while (true) { + String message = queue.getQueue().take(); + if ("exit".equalsIgnoreCase(message)) { + break; + } + System.out.println("Subscriber received: " + message); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.out.println("Subscriber interrupted."); + } + } +} From d22fe2ff4d22b83d6cccad6a1820c7455878e117 Mon Sep 17 00:00:00 2001 From: kshokh <128833441+kshokh@users.noreply.github.com> Date: Mon, 20 Oct 2025 23:05:18 -0400 Subject: [PATCH 2/2] Lesson 11 --- lessons/.gradle/8.13/checksums/checksums.lock | Bin 17 -> 17 bytes .../.gradle/8.13/checksums/md5-checksums.bin | Bin 19397 -> 19447 bytes .../.gradle/8.13/checksums/sha1-checksums.bin | Bin 21305 -> 21521 bytes .../executionHistory/executionHistory.bin | Bin 19717 -> 32298 bytes .../executionHistory/executionHistory.lock | Bin 17 -> 17 bytes .../.gradle/8.13/fileHashes/fileHashes.bin | Bin 18697 -> 20397 bytes .../.gradle/8.13/fileHashes/fileHashes.lock | Bin 17 -> 17 bytes .../buildOutputCleanup.lock | Bin 17 -> 17 bytes .../buildOutputCleanup/outputFiles.bin | Bin 18731 -> 19001 bytes .../{ => publisher_subscriber}/App.java | 2 +- .../MessageQueue.java | 2 +- .../{ => publisher_subscriber}/Publisher.java | 2 +- .../Subscriber.java | 2 +- .../lesson11/simplethreadpool/App.java | 27 ++++++++++ .../simplethreadpool/SimpleThreadPool.java | 47 ++++++++++++++++++ .../simplethreadpool/WorkerThread.java | 29 +++++++++++ 16 files changed, 107 insertions(+), 4 deletions(-) rename lessons/src/main/java/lessons/lesson11/{ => publisher_subscriber}/App.java (89%) rename lessons/src/main/java/lessons/lesson11/{ => publisher_subscriber}/MessageQueue.java (83%) rename lessons/src/main/java/lessons/lesson11/{ => publisher_subscriber}/Publisher.java (94%) rename lessons/src/main/java/lessons/lesson11/{ => publisher_subscriber}/Subscriber.java (93%) create mode 100644 lessons/src/main/java/lessons/lesson11/simplethreadpool/App.java create mode 100644 lessons/src/main/java/lessons/lesson11/simplethreadpool/SimpleThreadPool.java create mode 100644 lessons/src/main/java/lessons/lesson11/simplethreadpool/WorkerThread.java diff --git a/lessons/.gradle/8.13/checksums/checksums.lock b/lessons/.gradle/8.13/checksums/checksums.lock index 960c67a1f7404aa4e3a48ed89ab8f97b14b518c2..30ebe777a382c88b111d61284f97145c3070408b 100644 GIT binary patch literal 17 UcmZRcsq-yvYnJzY1_%fS05-$~xc~qF literal 17 UcmZRcsq-yvYnJzY1_umAu6 diff --git a/lessons/.gradle/8.13/checksums/md5-checksums.bin b/lessons/.gradle/8.13/checksums/md5-checksums.bin index 0e4ba3f7979a304252b07c4971501e24b06c4b96..0a35e9d8088ccc2e5c1dcbe1fb7fdcbacead2dda 100644 GIT binary patch delta 102 zcmX>)o$>p0#tkMCjKY&mC2k0O&eKW$`gNWm0~mN8oy;ovn(^jF#UJ7u4IIQaJ9@M* w8yN%TG=W$Vgaz8B-hGqb*3-OT&!+$J-*3)gU|^iZQf=}8CP0}a~mIJGk`&G{^VS#4Fa-CO!=#v%I`x3Ehmdg z{}Aw-u3Nk8>~b-v;L^#gGA9J`3z3 zHwMb;0Qni>vrAW*v^nYvv@uO1LMq_d@@j1u$}=bG$KmZES74M z2SC+8fKAt%kh(7-k*j5OSQsUK&yi7!x|O_M1Y()u2Cy!9&*eZG%`&hyOkF_BOs^yB F0svL^T7Lil delta 48 zcmV-00MGxCr~$dA0kAX}0W`BU7(fD(jT)$vO&jo&RUE*REgez<1o5#U_!qG-C=;_m GNcak~;1U1; diff --git a/lessons/.gradle/8.13/executionHistory/executionHistory.bin b/lessons/.gradle/8.13/executionHistory/executionHistory.bin index 89c5370b7c590da65e0d84000ce8bd72fafb96c2..a890ec331cf0ccd1ef26a8df33eb79a59052eeb0 100644 GIT binary patch literal 32298 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 a+0TdD^ZzS3Fs8*a-uAxp;j)9x+x!oMsD5Jr delta 49 zcmZ4Whp}}Q;{*{_1|SgKX!t^WqJzX_NeO92#>u`C%8Z&Ip^XkVfx_yW9X*b)003@6 B4>SM( diff --git a/lessons/.gradle/8.13/executionHistory/executionHistory.lock b/lessons/.gradle/8.13/executionHistory/executionHistory.lock index 76f66aa61155ad2a3bd909ef4bc639d07adc3d42..75aa13f4d16ed6e9da4c69513777e018e004aab2 100644 GIT binary patch literal 17 UcmZQB{cmo3foGa70|ZC`04?nUn*aa+ literal 17 UcmZQB{cmo3foGa70|YPw04>%7ga7~l diff --git a/lessons/.gradle/8.13/fileHashes/fileHashes.bin b/lessons/.gradle/8.13/fileHashes/fileHashes.bin index 9f95a891008ba666abcdf7734332eab4ab7b688c..8ee4c8b1a145eba2680ef3e1f50192fbaf0424e1 100644 GIT binary patch literal 20397 zcmeI4`!|$n9Khe1F{?td#UN62Ri{;S(WInWCYQEE)UH^HZlu}dvMTMtO4gQJCUiwN zN=lhEuGyw-Ria!rbjYcMbXi5&_Ic-dA06}VU$E!CqH!KF_$cT<#^Iy#vwNnakeVS+~o{8YaZQZt(G$i*KAe^#R>9kxpk$GJlUJZ?Zku|k5qp*R<&R@=1waKpCT(&>DOrNXYRuz-2CI?t)Xtc z5t!Ro5z2CPh%+%44JUlXf@Zgp)3P9F%$*_#-!U@!6z>H79vqC;$bZ02F`% zPyh-*0Vn_kpa2wr0#E=7KmjNK1)u;FfC5ke3P1rU00p1`6o3Ly017|>C;$bZ02F`% z>;mQpO+#N3=&w<;Hf||DI;OWQ^j96DewU&p6vdHn4F!hSQ%gpVGlv@K#rtP{)9@jj zJEyI@w*K@fZ0I;*<6I%z5Y@YHS{o#{7t9b|(pnxB&KUOCpgyn-3z4l~v@lKV>%BVO zy7?!4#yEowV>7lPYHRRm&sO`}zvJGfa;tek$Vk32fxa~w{E3&)QE44QNmfPV+Nwa= zw=oyI+%;;37*tIq+pz0vDxsXu=IZqr1kKy)K6;43AC|~A+V{_I%`D>k-iS3YE#a!S z4KW0}v)RVSh8Quwx9&nt%GMkg%ePaIA>kT@WT7k3;Gow>c^zIaB-YQ;PYihEhcDiG zc|j>{sD!S4N?(u8>A&$;TDjY+tH*D61Wz)3x!ck_Z#LTXfQ&$?pF*HG^k1~Z2!Z6Wz@JWu(4{6b;uy(Y&7_X^wC zJKBF|l9#SHezcMKUri5}DU2|>GCg?4=%6%*EY(Y;J20X$VZ8gYV1xG|c#hxF6avMo zVjHd|-ttSWoz)$09}dJD`R!rmpg#&|aOr(5N^_LRA51vWXU)}-k8I;KE<`&EP^&#R zn-l`2YRNWA&&S-dIr}n~*G2tPwa{FTc~%z~VjZ6t5+M0&aZu9=_Q>R&Z{3{Om#M88~er`DVpmZvrfap+%03` zE_B7`IYyY}xUvnS@Bi`Z3b^80$~hpJ#ud{mA6y4Tt+~fG8e+%KJatHm9~G%CycnK` zYNA$AyOv7KL$mF|#X&H-l}oEaJRBS7_A}d-hhwI1_IPo}+jKo$0H+PnT`nY`2gnd8HlPelhTw>>|DQ484NM#prWF57m?CptSNctBT_M zey$YxcAv~FZqAZ22K_?}4OO(uP1zW`_s+hG?@pa|&|lPd_1OI*3L|CmQH4Ma3uhZ? zss%DtP45q{>-^8QJk}h?%t7B94K)*VPy(c=UF3H}-< diff --git a/lessons/.gradle/8.13/fileHashes/fileHashes.lock b/lessons/.gradle/8.13/fileHashes/fileHashes.lock index 0ef8a01bd4be288bfdcae305b83fd5df93062bd6..c87c3ab16dc73c5e123863ce2dde932d9eb26630 100644 GIT binary patch literal 17 UcmZSHbmUsodQCnl1_;Oi05t;yIsgCw literal 17 UcmZSHbmUsodQCnl1_)pS05qWk*Z=?k diff --git a/lessons/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/lessons/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 00e9ec4ec98dc7e0ed11b35c1301569eab70d77e..5587ac66d8a567273a76436f598e74a093d84345 100644 GIT binary patch literal 17 TcmZQBI2fQ2lb$5T00ABVCYl2< literal 17 TcmZQBI2fQ2lb$5T009C3CSn5k diff --git a/lessons/.gradle/buildOutputCleanup/outputFiles.bin b/lessons/.gradle/buildOutputCleanup/outputFiles.bin index a6faea7c6a1d78ece40f4ebf3fab7ad7010ea4f9..5ca6af5accb89310be231e1ff5f8cd375734c1ac 100644 GIT binary patch delta 412 zcmZ2IiE-x?#tkMCjxw`&;v~MzU|-Du1|GrxpPF~~syCU)LY^dN$nBptedUemzZ!tl|Kf=UsOgk8D`JLxJMBGbsa<7Df zz-=u)e_!vV7omdclb1>a2z(EhdAwTez(=SFwv*pVSO^Hc>bZ8}pzcAap!Q^0NredY zHnGp)xo(b7!Lu;CbT;vQ{gVCjHdMSACT`SbxEJ$e zQ%MB}4;2Bo*2~K|p^E)sibFQH+E4l>u@@>n9VVV!q_m*%hw3G$`0mNRl3Gkm8#gNc k5Z`E!Av)R7m&H#tkMCg1obM;v~MzU|-Du1|GqaOC3u?R!U;> XUMVFeM$e6kKg2g0To9Y== { + System.out.println(Thread.currentThread().getName() + " executing task " + taskId); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + }); + } + + try { + Thread.sleep(5000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + + pool.shutdown(); + } +} diff --git a/lessons/src/main/java/lessons/lesson11/simplethreadpool/SimpleThreadPool.java b/lessons/src/main/java/lessons/lesson11/simplethreadpool/SimpleThreadPool.java new file mode 100644 index 0000000..6aa4449 --- /dev/null +++ b/lessons/src/main/java/lessons/lesson11/simplethreadpool/SimpleThreadPool.java @@ -0,0 +1,47 @@ +package lessons.lesson11.simplethreadpool; + +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +public class SimpleThreadPool { + + @Getter + private final BlockingQueue taskQueue; + private final List workers; + private volatile boolean isRunning = true; + + public SimpleThreadPool(int threadCount) { + this.taskQueue = new LinkedBlockingQueue<>(); + this.workers = new ArrayList<>(); + + for (int i = 0; i < threadCount; i++) { + WorkerThread worker = new WorkerThread(taskQueue); + worker.setName("Worker-" + (i + 1)); + worker.start(); + workers.add(worker); + } + + System.out.println("Thread pool initialized with " + threadCount + " threads."); + } + + public void submit(Runnable task) { + if (!isRunning) { + throw new IllegalStateException("Thread pool is shutting down."); + } + taskQueue.offer(task); + } + + public void shutdown() { + System.out.println("Shutting down thread pool..."); + isRunning = false; + + for (WorkerThread worker : workers) { + worker.stopWorker(); + } + System.out.println("Thread pool shutdown complete."); + } +} diff --git a/lessons/src/main/java/lessons/lesson11/simplethreadpool/WorkerThread.java b/lessons/src/main/java/lessons/lesson11/simplethreadpool/WorkerThread.java new file mode 100644 index 0000000..4af1033 --- /dev/null +++ b/lessons/src/main/java/lessons/lesson11/simplethreadpool/WorkerThread.java @@ -0,0 +1,29 @@ +package lessons.lesson11.simplethreadpool; + +import lombok.RequiredArgsConstructor; + +import java.util.concurrent.BlockingQueue; + +@RequiredArgsConstructor +public class WorkerThread extends Thread { + private final BlockingQueue taskQueue; + private volatile boolean running = true; + + @Override + public void run() { + while (running) { + try { + Runnable task = taskQueue.take(); + task.run(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + System.out.println(Thread.currentThread().getName() + " interrupted."); + } + } + } + + public void stopWorker() { + running = false; + this.interrupt(); + } +}