From 2760252a1380300d120c2dda65bcfa9ae5cdd533 Mon Sep 17 00:00:00 2001 From: Mike Jensen Date: Fri, 3 Jan 2014 15:39:40 -0700 Subject: [PATCH] Avoid doing a Thread.sleep() and instead do a wait and notify. --- test/AtomicIntegerTest.java | 30 +++++++++++++++++++----------- test/AtomicLongTest.java | 30 +++++++++++++++++++----------- test/AtomicReferenceTest.java | 30 +++++++++++++++++++----------- 3 files changed, 57 insertions(+), 33 deletions(-) diff --git a/test/AtomicIntegerTest.java b/test/AtomicIntegerTest.java index 1736fe11c2..7e2326b31f 100644 --- a/test/AtomicIntegerTest.java +++ b/test/AtomicIntegerTest.java @@ -1,20 +1,26 @@ +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; public class AtomicIntegerTest { private static void runTest(final boolean increment, final int threadCount, final int iterationsPerThread) { - // we assume a 1ms delay per thread to try to get them all to start at the same time - final long startTime = System.currentTimeMillis() + threadCount + 10; final AtomicInteger result = new AtomicInteger(); final AtomicInteger threadDoneCount = new AtomicInteger(); + // only using an AtomicBoolean here so I don't need two variables to do the synchronize/wait/notify + final AtomicBoolean threadsStart = new AtomicBoolean(false); for (int i = 0; i < threadCount; i++) { new Thread(new Runnable() { @Override public void run() { try { - waitTillReady(); + try { + waitTillReady(); + } catch (InterruptedException e) { + // let thread exit + return; + } doOperation(); } finally { synchronized (threadDoneCount) { @@ -25,14 +31,10 @@ public class AtomicIntegerTest { } } - private void waitTillReady() { - long sleepTime = System.currentTimeMillis() - startTime; - if (sleepTime > 0) { - try { - Thread.sleep(sleepTime); - } catch (InterruptedException e) { - // let thread exit - return; + private void waitTillReady() throws InterruptedException { + synchronized (threadsStart) { + while (! threadsStart.get()) { + threadsStart.wait(); } } } @@ -60,6 +62,12 @@ public class AtomicIntegerTest { }).start(); } + synchronized (threadsStart) { + threadsStart.set(true); + + threadsStart.notifyAll(); + } + synchronized (threadDoneCount) { while (threadDoneCount.get() < threadCount) { try { diff --git a/test/AtomicLongTest.java b/test/AtomicLongTest.java index db6bd618c0..1ec9c89303 100644 --- a/test/AtomicLongTest.java +++ b/test/AtomicLongTest.java @@ -1,20 +1,26 @@ +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; public class AtomicLongTest { private static void runTest(final boolean increment, final int threadCount, final int iterationsPerThread) { - // we assume a 1ms delay per thread to try to get them all to start at the same time - final long startTime = System.currentTimeMillis() + threadCount + 10; final AtomicLong result = new AtomicLong(); final AtomicLong threadDoneCount = new AtomicLong(); + // only using an AtomicBoolean here so I don't need two variables to do the synchronize/wait/notify + final AtomicBoolean threadsStart = new AtomicBoolean(false); for (int i = 0; i < threadCount; i++) { new Thread(new Runnable() { @Override public void run() { try { - waitTillReady(); + try { + waitTillReady(); + } catch (InterruptedException e) { + // let thread exit + return; + } doOperation(); } finally { synchronized (threadDoneCount) { @@ -25,14 +31,10 @@ public class AtomicLongTest { } } - private void waitTillReady() { - long sleepTime = System.currentTimeMillis() - startTime; - if (sleepTime > 0) { - try { - Thread.sleep(sleepTime); - } catch (InterruptedException e) { - // let thread exit - return; + private void waitTillReady() throws InterruptedException { + synchronized (threadsStart) { + while (! threadsStart.get()) { + threadsStart.wait(); } } } @@ -60,6 +62,12 @@ public class AtomicLongTest { }).start(); } + synchronized (threadsStart) { + threadsStart.set(true); + + threadsStart.notifyAll(); + } + synchronized (threadDoneCount) { while (threadDoneCount.get() < threadCount) { try { diff --git a/test/AtomicReferenceTest.java b/test/AtomicReferenceTest.java index 69d16d850a..2ebce10475 100644 --- a/test/AtomicReferenceTest.java +++ b/test/AtomicReferenceTest.java @@ -1,20 +1,26 @@ +import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; public class AtomicReferenceTest { private static void runTest(final int threadCount, final int iterationsPerThread) { - // we assume a 1ms delay per thread to try to get them all to start at the same time - final long startTime = System.currentTimeMillis() + threadCount + 10; final AtomicReference result = new AtomicReference(0); final AtomicInteger threadDoneCount = new AtomicInteger(0); + // only using an AtomicBoolean here so I don't need two variables to do the synchronize/wait/notify + final AtomicBoolean threadsStart = new AtomicBoolean(false); for (int i = 0; i < threadCount; i++) { new Thread(new Runnable() { @Override public void run() { try { - waitTillReady(); + try { + waitTillReady(); + } catch (InterruptedException e) { + // let thread exit + return; + } doOperation(); } finally { synchronized (threadDoneCount) { @@ -25,14 +31,10 @@ public class AtomicReferenceTest { } } - private void waitTillReady() { - long sleepTime = System.currentTimeMillis() - startTime; - if (sleepTime > 0) { - try { - Thread.sleep(sleepTime); - } catch (InterruptedException e) { - // let thread exit - return; + private void waitTillReady() throws InterruptedException { + synchronized (threadsStart) { + while (! threadsStart.get()) { + threadsStart.wait(); } } } @@ -48,6 +50,12 @@ public class AtomicReferenceTest { }).start(); } + synchronized (threadsStart) { + threadsStart.set(true); + + threadsStart.notifyAll(); + } + synchronized (threadDoneCount) { while (threadDoneCount.get() < threadCount) { try {