From 57212029408d05c96d7e1b84850f0037636d5677 Mon Sep 17 00:00:00 2001 From: Mustafa Muhhamed Date: Sat, 7 Dec 2024 16:14:00 +0200 Subject: [PATCH 1/5] Fixed busy waiting in point #2 --- .../java/com/iluwatar/twin/BallThread.java | 50 +++++++++++-------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/twin/src/main/java/com/iluwatar/twin/BallThread.java b/twin/src/main/java/com/iluwatar/twin/BallThread.java index 9d4d9cf71a76..fd777cdae59b 100644 --- a/twin/src/main/java/com/iluwatar/twin/BallThread.java +++ b/twin/src/main/java/com/iluwatar/twin/BallThread.java @@ -24,39 +24,45 @@ */ package com.iluwatar.twin; -import lombok.Setter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import lombok.extern.slf4j.Slf4j; /** - * This class is a UI thread for drawing the {@link BallItem}, and provide the method for suspend + * This class is a UI thread for drawing the {@link BallItem}, and provides methods for suspend * and resume. It holds the reference of {@link BallItem} to delegate the draw task. */ @Slf4j public class BallThread extends Thread { - @Setter - private BallItem twin; - - private volatile boolean isSuspended; + private static final Logger LOGGER = LoggerFactory.getLogger(BallThread.class); private volatile boolean isRunning = true; + private volatile boolean isSuspended = false; + private final Object lock = new Object(); + private final BallItem twin; - /** - * Run the thread. - */ - public void run() { + public BallThread(BallItem twin) { + this.twin = twin; + } - while (isRunning) { - if (!isSuspended) { - twin.draw(); + @Override + public void run() { + try { + while (isRunning) { + synchronized (lock) { + while (isSuspended) { + lock.wait(); + } + } + twin.doDraw(); twin.move(); - } - try { Thread.sleep(250); - } catch (InterruptedException e) { - throw new RuntimeException(e); } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + throw new RuntimeException(e); } } @@ -66,13 +72,15 @@ public void suspendMe() { } public void resumeMe() { - isSuspended = false; + synchronized (lock) { + isSuspended = false; + lock.notifyAll(); + } LOGGER.info("Begin to resume BallThread"); } public void stopMe() { - this.isRunning = false; - this.isSuspended = true; + isRunning = false; + resumeMe(); // Ensure the thread exits if it is waiting } } - From f67310bcdfe07811251f0233375b195cba5b5f9e Mon Sep 17 00:00:00 2001 From: Mustafa Muhhamed Date: Sat, 7 Dec 2024 17:22:28 +0200 Subject: [PATCH 2/5] Fixed busy waiting in point 2 --- .../java/com/iluwatar/twin/BallThread.java | 31 +++++++++++++------ 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/twin/src/main/java/com/iluwatar/twin/BallThread.java b/twin/src/main/java/com/iluwatar/twin/BallThread.java index fd777cdae59b..4e5270ce8bf4 100644 --- a/twin/src/main/java/com/iluwatar/twin/BallThread.java +++ b/twin/src/main/java/com/iluwatar/twin/BallThread.java @@ -51,14 +51,15 @@ public BallThread(BallItem twin) { public void run() { try { while (isRunning) { - synchronized (lock) { - while (isSuspended) { + if (isSuspended) { + synchronized (lock) { lock.wait(); } + } else { + twin.doDraw(); + twin.move(); + Thread.sleep(250); } - twin.doDraw(); - twin.move(); - Thread.sleep(250); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); @@ -66,21 +67,33 @@ public void run() { } } + /** + * Suspend the thread. + */ public void suspendMe() { isSuspended = true; LOGGER.info("Begin to suspend BallThread"); } + /** + * Notify run to resume. + */ public void resumeMe() { + isSuspended = false; + LOGGER.info("Begin to resume BallThread"); synchronized (lock) { - isSuspended = false; lock.notifyAll(); } - LOGGER.info("Begin to resume BallThread"); } + /** + * Stop running thread. + */ public void stopMe() { - isRunning = false; - resumeMe(); // Ensure the thread exits if it is waiting + this.isRunning = false; + this.isSuspended = true; + synchronized (lock) { + lock.notifyAll(); + } } } From f4c4f4bb150e585afffba9d012bb2661552569fa Mon Sep 17 00:00:00 2001 From: Mustafa Muhhamed Date: Sat, 7 Dec 2024 17:29:46 +0200 Subject: [PATCH 3/5] Update (fixed busy waiting in point 2) --- twin/src/main/java/com/iluwatar/twin/BallThread.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/twin/src/main/java/com/iluwatar/twin/BallThread.java b/twin/src/main/java/com/iluwatar/twin/BallThread.java index 4e5270ce8bf4..ab21107b2d27 100644 --- a/twin/src/main/java/com/iluwatar/twin/BallThread.java +++ b/twin/src/main/java/com/iluwatar/twin/BallThread.java @@ -32,7 +32,6 @@ * This class is a UI thread for drawing the {@link BallItem}, and provides methods for suspend * and resume. It holds the reference of {@link BallItem} to delegate the draw task. */ - @Slf4j public class BallThread extends Thread { @@ -43,6 +42,11 @@ public class BallThread extends Thread { private final Object lock = new Object(); private final BallItem twin; + /** + * Constructor. + * + * @param twin the BallItem instance + */ public BallThread(BallItem twin) { this.twin = twin; } From dacb230a764101d59ae85c6f8a00f33100ac4fc6 Mon Sep 17 00:00:00 2001 From: Mustafa Muhhamed Date: Sat, 7 Dec 2024 17:39:46 +0200 Subject: [PATCH 4/5] (update2) Fixed busy waiting in point 2 --- twin/src/main/java/com/iluwatar/twin/BallThread.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/twin/src/main/java/com/iluwatar/twin/BallThread.java b/twin/src/main/java/com/iluwatar/twin/BallThread.java index ab21107b2d27..20a94f9feaff 100644 --- a/twin/src/main/java/com/iluwatar/twin/BallThread.java +++ b/twin/src/main/java/com/iluwatar/twin/BallThread.java @@ -6,7 +6,7 @@ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights + * in the Software without restriction, including but not limited to the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: From 23a95d1fd10c22349b1f19bea0ba27443621485b Mon Sep 17 00:00:00 2001 From: Mustafa Muhhamed Date: Sat, 7 Dec 2024 18:34:20 +0200 Subject: [PATCH 5/5] fixing-busy waiting loop #BallThread --- .../java/com/iluwatar/twin/BallThread.java | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/twin/src/main/java/com/iluwatar/twin/BallThread.java b/twin/src/main/java/com/iluwatar/twin/BallThread.java index 20a94f9feaff..177e6fdb4617 100644 --- a/twin/src/main/java/com/iluwatar/twin/BallThread.java +++ b/twin/src/main/java/com/iluwatar/twin/BallThread.java @@ -6,7 +6,7 @@ * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including but not limited to the rights + * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: @@ -55,15 +55,14 @@ public BallThread(BallItem twin) { public void run() { try { while (isRunning) { - if (isSuspended) { - synchronized (lock) { + synchronized (lock) { + while (isSuspended) { lock.wait(); } - } else { - twin.doDraw(); - twin.move(); - Thread.sleep(250); } + twin.doDraw(); + twin.move(); + Thread.sleep(250); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); @@ -83,21 +82,18 @@ public void suspendMe() { * Notify run to resume. */ public void resumeMe() { - isSuspended = false; - LOGGER.info("Begin to resume BallThread"); synchronized (lock) { + isSuspended = false; lock.notifyAll(); } + LOGGER.info("Begin to resume BallThread"); } /** * Stop running thread. */ public void stopMe() { - this.isRunning = false; - this.isSuspended = true; - synchronized (lock) { - lock.notifyAll(); - } + isRunning = false; + resumeMe(); // Ensure the thread exits if it is waiting } }