From 8267d31d31d948722c316d3cdf106027a6b1ca23 Mon Sep 17 00:00:00 2001 From: Sander Hautvast Date: Fri, 20 Sep 2019 15:59:16 +0200 Subject: [PATCH] added finalize and shutdownhooks --- readme.md | 6 ++++-- src/chapter7/Finalizing.java | 24 ++++++++++++++++++++++++ src/chapter7/OnShutdown.java | 12 ++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 src/chapter7/Finalizing.java create mode 100644 src/chapter7/OnShutdown.java diff --git a/readme.md b/readme.md index 61309b7..50ee2e5 100644 --- a/readme.md +++ b/readme.md @@ -7,7 +7,7 @@ The code is presented in 'puzzler' style. So it can contain unsafe code and it's - [`SafeSequence`](src/chapter1/SafeSequence.java) Uses *synchronized* to guarantee ordered reads/updates. - [`Waiter`](src/chapter1/Waiter.java) Object.wait() is tricky. For instance the user must use _synchronized_ but in this case does not lock on the monitor. Other threads can still 'synchronize' on it as shown. The more well known catch is that there can be spurious wakeups, so the user needs some boolean value to make sure a wakeup was valid (not shown here). -### cretans +### Cretans _'All the Cretans are liars'_ -- Epimenides the Cretan (https://en.wikipedia.org/wiki/Epimenides_paradox) @@ -22,7 +22,7 @@ The motivation for this code is that it's easy to shoot yourself in the foot wit - [`SynchronizedCretan5`](src/chapter1/cretans/SynchronizedCretan5.java) Is tricky because _synchronized_ on a method uses _this_ as the lock object. So update() and compare() might not use the same lock object. ### Sleepers -This code shows the many ways you historically have to make the thread stop for a while. Should never be necessary. In theory. This approach is still very common even in production code. +This code shows the many ways you historically have to make the thread stop for a while. Should never be necessary ... in theory. It's still very common even in production code. Sometimes you just can't get around it. * [`Sleeper1`](src/chapter1/sleepers/Sleeper1.java) Still the most used way, using Thread.sleep() where the argument is the number of milliseconds. It is not theoretical that a developer mistakenly thinks they are seconds. * [`Sleeper2`](src/chapter1/sleepers/Sleeper2.java) The more modern remedy where the unit is explicit. * [`Sleeper3a`](src/chapter1/sleepers/Sleeper3a.java) Again using Object.wait(). @@ -67,3 +67,5 @@ This code shows the many ways you historically have to make the thread stop for ## Chapter 7 Task Cancellation - [`TrickyTaskCancellation`](src/chapter7/TrickyTaskCancellation.java) Shows the subtle difference between interupted() and isInterrupted. - [`Shutdown`](src/chapter7/Shutdown.java) and [`ShutdownNow`](src/chapter7/ShutdownNow.java) Show the difference between both methods. There are still a lot of tasks in queue when shutdown runs, and they will still be executed. After shutdownNow() there are less dots indicating earlier stop. The currently running task is being interrupted while sleeping. +- [`Finalizing`](src/chapter7/Finalizing.java) The single Finalizer thread is busy finalizing, only until the JVM exits. If you have resources to be closed outside the process, you have no guarantee that that will actually happen. @Deprecated +- [`OnShutdown`](src/chapter7/OnShutdown.java) Shutdown hooks are still a valid way to do things before the JVM exits. diff --git a/src/chapter7/Finalizing.java b/src/chapter7/Finalizing.java new file mode 100644 index 0000000..defce6a --- /dev/null +++ b/src/chapter7/Finalizing.java @@ -0,0 +1,24 @@ +package chapter7; + +import java.util.concurrent.TimeUnit; + +public class Finalizing { + public static void main(String[] args) throws InterruptedException { + for (int i = 0; i < 100; i++) { + new Finalizing(); + } + System.gc(); + TimeUnit.SECONDS.sleep(10); + } + + @Override + protected void finalize() throws Throwable { + System.out.println("finalizing..."); + + TimeUnit.SECONDS.sleep(1); + + System.out.printf("is taking a long time for %s%n", Thread.currentThread().getName()); + + throw new Exception("oops"); + } +} diff --git a/src/chapter7/OnShutdown.java b/src/chapter7/OnShutdown.java new file mode 100644 index 0000000..7c6f37c --- /dev/null +++ b/src/chapter7/OnShutdown.java @@ -0,0 +1,12 @@ +package chapter7; + +public class OnShutdown { + public static void main(String[] args) { + Runtime.getRuntime().addShutdownHook(new Thread(){ + @Override + public void run() { + System.out.println("going down"); + } + }); + } +}