From 3f60957c07241b8410c8d37718d38f790f0f20d0 Mon Sep 17 00:00:00 2001 From: Sander Hautvast Date: Tue, 24 Sep 2019 17:00:02 +0200 Subject: [PATCH] minor textual updates --- readme.md | 4 ++-- src/chapter1/SafeSequence.java | 3 ++- src/chapter1/UnsafeSequence.java | 1 + src/chapter1/Waiter.java | 3 ++- src/chapter1/sleepers/Sleeper1.java | 1 - src/chapter1/sleepers/Sleeper3b.java | 2 +- 6 files changed, 8 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index df9c65c..7d7afd7 100644 --- a/readme.md +++ b/readme.md @@ -1,5 +1,5 @@ # Java Concurrency in Practice -I created this code to complement the book by showing the pitfalls of using threads in java and by showing the correct use of some concurrency primitives since java 1.5. It is no replacement for the book and does not necessarily cover all aspects covered. Some code goes beyond the book for instance when trying to actually prove what is said, for instance the thread-unsafety of java.util.HashMap. +I created this code to complement the book by showing the pitfalls of using threads in java and by showing the correct use of some concurrency primitives since java 1.5. It is no replacement for the book and does not necessarily cover all of its aspects. Some code goes beyond the book for instance when trying to actually prove what is said, for instance the thread-unsafety of java.util.HashMap. The code is presented in 'puzzler' style. So it can contain unsafe code and it's up to the reader to discover that. This readme is added as an explanation. ## Chapter 1 Fundamentals @@ -32,7 +32,7 @@ This code shows the many ways you historically have to make the thread stop for ## Chapter 2 Thread Safety - [`LazyInit`](src/chapter2/LazyInit.java) Taken from Listing 2.3. Lazy initialization might seem a good way to postpone initialization until it is actually needed, but introduces new problems (race conditions). This was not uncommon in older applications. -- [`SafeLazyInit`](src/chapter2/SafeLazyInit.java) Is safe while not being very scalable. Readonly singletons are better initialized while starting up, for instance using dependency injection. +- [`SafeLazyInit`](src/chapter2/SafeLazyInit.java) Is safe while not being very scalable. Readonly singletons are better initialized while starting up, for instance using dependency injection. See https://www.javaworld.com/article/2074979/double-checked-locking--clever--but-broken.html for the definitive answer on double-checked locking ## Chapter 3 Sharing Objects - [`AttemptToShowReordering`](src/chapter3/AttemptToShowReordering.java) The java memory model facilitates modern processors that are free to reorder instructions, if (and only if) reordering would not harm sequential execution. While this is accepted theory, it is surprisingly difficult (if not impossible) to show reordering on Intel processors. The code tries to find a situation where variables _b_ or _c_ are set but _a_ is not. diff --git a/src/chapter1/SafeSequence.java b/src/chapter1/SafeSequence.java index e0a0b8b..64715f3 100644 --- a/src/chapter1/SafeSequence.java +++ b/src/chapter1/SafeSequence.java @@ -7,7 +7,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /* - * Basic example taken from JCIP listing 1.2 (also slightly altered) + * Basic example taken from JCIP listing 1.2 (slightly altered) */ public class SafeSequence { private final List collectedValues = new CopyOnWriteArrayList<>(); @@ -20,6 +20,7 @@ public class SafeSequence { } @Test + @SuppressWarnings("Duplicates") public void test() throws InterruptedException { TestHarness testHarness = new TestHarness(8); diff --git a/src/chapter1/UnsafeSequence.java b/src/chapter1/UnsafeSequence.java index a6fdb1b..4492471 100644 --- a/src/chapter1/UnsafeSequence.java +++ b/src/chapter1/UnsafeSequence.java @@ -22,6 +22,7 @@ public class UnsafeSequence { } @Test + @SuppressWarnings("Duplicates") public void test() throws InterruptedException { TestHarness testHarness = new TestHarness(8); diff --git a/src/chapter1/Waiter.java b/src/chapter1/Waiter.java index ab6f243..e64d9fe 100644 --- a/src/chapter1/Waiter.java +++ b/src/chapter1/Waiter.java @@ -34,11 +34,12 @@ public class Waiter { // wait now System.out.println("1 wait"); + synchronized (lock) { lock.wait(); } - System.out.println("4 wait no more"); + System.out.println("4 wait no longer"); executor.shutdownNow(); } diff --git a/src/chapter1/sleepers/Sleeper1.java b/src/chapter1/sleepers/Sleeper1.java index 42666bb..5b0a388 100644 --- a/src/chapter1/sleepers/Sleeper1.java +++ b/src/chapter1/sleepers/Sleeper1.java @@ -2,7 +2,6 @@ package chapter1.sleepers; public class Sleeper1 { - // NB they are milliseconds public static void main(String[] args) throws InterruptedException { System.out.println("sleep"); diff --git a/src/chapter1/sleepers/Sleeper3b.java b/src/chapter1/sleepers/Sleeper3b.java index 8952228..df3a0d5 100644 --- a/src/chapter1/sleepers/Sleeper3b.java +++ b/src/chapter1/sleepers/Sleeper3b.java @@ -7,7 +7,7 @@ import java.util.Date; public class Sleeper3b { - /* what does this print? */ + /* what does this print and does that bother you? */ public void sleep() { synchronized (this) { try {