Skip to content

Commit b4dd083

Browse files
committed
Initial commit of Effective Java, 3e source code, only eight months too late.
0 parents  commit b4dd083

File tree

156 files changed

+4385
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

156 files changed

+4385
-0
lines changed

.gitignore

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
2+
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
3+
4+
# I [jjb] added this to ignore emacs autosaves
5+
*~
6+
7+
# User-specific stuff
8+
# .idea/**/workspace.xml
9+
# .idea/**/tasks.xml
10+
# .idea/**/usage.statistics.xml
11+
# .idea/**/dictionaries
12+
# .idea/**/shelf
13+
.idea
14+
15+
# Sensitive or high-churn files
16+
# .idea/**/dataSources/
17+
# .idea/**/dataSources.ids
18+
# .idea/**/dataSources.local.xml
19+
# .idea/**/sqlDataSources.xml
20+
# .idea/**/dynamic.xml
21+
# .idea/**/uiDesigner.xml
22+
# .idea/**/dbnavigator.xml
23+
24+
# Gradle
25+
.idea/**/gradle.xml
26+
.idea/**/libraries
27+
28+
# Gradle and Maven with auto-import
29+
# When using Gradle or Maven with auto-import, you should exclude module files,
30+
# since they will be recreated, and may cause churn. Uncomment if using
31+
# auto-import.
32+
# .idea/modules.xml
33+
# .idea/*.iml
34+
# .idea/modules
35+
36+
# CMake
37+
cmake-build-*/
38+
39+
# Mongo Explorer plugin
40+
# .idea/**/mongoSettings.xml
41+
42+
# File-based project format
43+
*.iws
44+
*.iml
45+
46+
# IntelliJ
47+
out/
48+
49+
# mpeltonen/sbt-idea plugin
50+
.idea_modules/
51+
52+
# JIRA plugin
53+
atlassian-ide-plugin.xml
54+
55+
# Cursive Clojure plugin
56+
# .idea/replstate.xml
57+
58+
# Crashlytics plugin (for Android Studio and IntelliJ)
59+
com_crashlytics_export_strings.xml
60+
crashlytics.properties
61+
crashlytics-build.properties
62+
fabric.properties
63+
64+
# Editor-based Rest Client
65+
# .idea/httpRequests
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package effectivejava.chapter10.item74;
2+
3+
public class IndexOutOfBoundsException extends RuntimeException {
4+
private final int lowerBound;
5+
private final int upperBound;
6+
private final int index;
7+
8+
/**
9+
* Constructs an IndexOutOfBoundsException.
10+
*
11+
* @param lowerBound the lowest legal index value
12+
* @param upperBound the highest legal index value plus one
13+
* @param index the actual index value
14+
*/
15+
public IndexOutOfBoundsException(int lowerBound, int upperBound,
16+
int index) {
17+
// Generate a detail message that captures the failure
18+
super(String.format(
19+
"Lower bound: %d, Upper bound: %d, Index: %d",
20+
lowerBound, upperBound, index));
21+
22+
// Save failure information for programmatic access
23+
this.lowerBound = lowerBound;
24+
this.upperBound = upperBound;
25+
this.index = index;
26+
}
27+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package effectivejava.chapter11.item78.brokenstopthread;
2+
import java.util.concurrent.*;
3+
4+
// Broken! - How long would you expect this program to run? (Page 312)
5+
public class StopThread {
6+
private static boolean stopRequested;
7+
8+
public static void main(String[] args)
9+
throws InterruptedException {
10+
Thread backgroundThread = new Thread(() -> {
11+
int i = 0;
12+
while (!stopRequested)
13+
i++;
14+
});
15+
backgroundThread.start();
16+
17+
TimeUnit.SECONDS.sleep(1);
18+
stopRequested = true;
19+
}
20+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package effectivejava.chapter11.item78.fixedstopthread1;
2+
import java.util.concurrent.*;
3+
4+
// Properly synchronized cooperative thread termination
5+
public class StopThread {
6+
private static boolean stopRequested;
7+
8+
private static synchronized void requestStop() {
9+
stopRequested = true;
10+
}
11+
12+
private static synchronized boolean stopRequested() {
13+
return stopRequested;
14+
}
15+
16+
public static void main(String[] args)
17+
throws InterruptedException {
18+
Thread backgroundThread = new Thread(() -> {
19+
int i = 0;
20+
while (!stopRequested())
21+
i++;
22+
});
23+
backgroundThread.start();
24+
25+
TimeUnit.SECONDS.sleep(1);
26+
requestStop();
27+
}
28+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package effectivejava.chapter11.item78.fixedstopthread2;
2+
import java.util.concurrent.*;
3+
4+
// Cooperative thread termination with a volatile field
5+
public class StopThread {
6+
private static volatile boolean stopRequested;
7+
8+
public static void main(String[] args)
9+
throws InterruptedException {
10+
Thread backgroundThread = new Thread(() -> {
11+
int i = 0;
12+
while (!stopRequested)
13+
i++;
14+
});
15+
backgroundThread.start();
16+
17+
TimeUnit.SECONDS.sleep(1);
18+
stopRequested = true;
19+
}
20+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package effectivejava.chapter11.item79;
2+
import java.util.*;
3+
4+
// Reusable forwarding class (Page XXX)
5+
public class ForwardingSet<E> implements Set<E> {
6+
private final Set<E> s;
7+
public ForwardingSet(Set<E> s) { this.s = s; }
8+
9+
public void clear() { s.clear(); }
10+
public boolean contains(Object o) { return s.contains(o); }
11+
public boolean isEmpty() { return s.isEmpty(); }
12+
public int size() { return s.size(); }
13+
public Iterator<E> iterator() { return s.iterator(); }
14+
public boolean add(E e) { return s.add(e); }
15+
public boolean remove(Object o) { return s.remove(o); }
16+
public boolean containsAll(Collection<?> c)
17+
{ return s.containsAll(c); }
18+
public boolean addAll(Collection<? extends E> c)
19+
{ return s.addAll(c); }
20+
public boolean removeAll(Collection<?> c)
21+
{ return s.removeAll(c); }
22+
public boolean retainAll(Collection<?> c)
23+
{ return s.retainAll(c); }
24+
public Object[] toArray() { return s.toArray(); }
25+
public <T> T[] toArray(T[] a) { return s.toArray(a); }
26+
@Override public boolean equals(Object o)
27+
{ return s.equals(o); }
28+
@Override public int hashCode() { return s.hashCode(); }
29+
@Override public String toString() { return s.toString(); }
30+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package effectivejava.chapter11.item79;
2+
import java.util.*;
3+
import java.util.concurrent.CopyOnWriteArrayList;
4+
5+
// Broken - invokes alien method from synchronized block!
6+
public class ObservableSet<E> extends ForwardingSet<E> {
7+
public ObservableSet(Set<E> set) { super(set); }
8+
9+
// private final List<SetObserver<E>> observers
10+
// = new ArrayList<>();
11+
12+
// public void addObserver(SetObserver<E> observer) {
13+
// synchronized(observers) {
14+
// observers.add(observer);
15+
// }
16+
// }
17+
//
18+
// public boolean removeObserver(SetObserver<E> observer) {
19+
// synchronized(observers) {
20+
// return observers.remove(observer);
21+
// }
22+
// }
23+
24+
// private void notifyElementAdded(E element) {
25+
// synchronized(observers) {
26+
// for (SetObserver<E> observer : observers)
27+
// observer.added(this, element);
28+
// }
29+
// }
30+
31+
// // Alien method moved outside of synchronized block - open calls
32+
// private void notifyElementAdded(E element) {
33+
// List<SetObserver<E>> snapshot = null;
34+
// synchronized(observers) {
35+
// snapshot = new ArrayList<>(observers);
36+
// }
37+
// for (SetObserver<E> observer : snapshot)
38+
// observer.added(this, element);
39+
// }
40+
41+
// Thread-safe observable set with CopyOnWriteArrayList
42+
private final List<SetObserver<E>> observers =
43+
new CopyOnWriteArrayList<>();
44+
45+
public void addObserver(SetObserver<E> observer) {
46+
observers.add(observer);
47+
}
48+
49+
public boolean removeObserver(SetObserver<E> observer) {
50+
return observers.remove(observer);
51+
}
52+
53+
private void notifyElementAdded(E element) {
54+
for (SetObserver<E> observer : observers)
55+
observer.added(this, element);
56+
}
57+
58+
@Override public boolean add(E element) {
59+
boolean added = super.add(element);
60+
if (added)
61+
notifyElementAdded(element);
62+
return added;
63+
}
64+
65+
@Override public boolean addAll(Collection<? extends E> c) {
66+
boolean result = false;
67+
for (E element : c)
68+
result |= add(element); // Calls notifyElementAdded
69+
return result;
70+
}
71+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package effectivejava.chapter11.item79;
2+
3+
// Set obeserver callback interface - Page 266
4+
public interface SetObserver<E> {
5+
// Invoked when an element is added to the observable set
6+
void added(ObservableSet<E> set, E element);
7+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package effectivejava.chapter11.item79;
2+
import java.util.*;
3+
4+
// Simple test of ObservableSet - Page 318
5+
public class Test1 {
6+
public static void main(String[] args) {
7+
ObservableSet<Integer> set =
8+
new ObservableSet<>(new HashSet<>());
9+
10+
set.addObserver((s, e) -> System.out.println(e));
11+
12+
for (int i = 0; i < 100; i++)
13+
set.add(i);
14+
}
15+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package effectivejava.chapter11.item79;
2+
import java.util.*;
3+
4+
// More complex test of ObservableSet - Page 318-9
5+
public class Test2 {
6+
public static void main(String[] args) {
7+
ObservableSet<Integer> set =
8+
new ObservableSet<>(new HashSet<>());
9+
10+
set.addObserver(new SetObserver<>() {
11+
public void added(ObservableSet<Integer> s, Integer e) {
12+
System.out.println(e);
13+
if (e == 23)
14+
s.removeObserver(this);
15+
}
16+
});
17+
18+
for (int i = 0; i < 100; i++)
19+
set.add(i);
20+
}
21+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package effectivejava.chapter11.item79;
2+
import java.util.*;
3+
import java.util.concurrent.ExecutionException;
4+
import java.util.concurrent.ExecutorService;
5+
import java.util.concurrent.Executors;
6+
7+
// Simple test of ObservableSet - Page 319
8+
public class Test3 {
9+
public static void main(String[] args) {
10+
ObservableSet<Integer> set =
11+
new ObservableSet<>(new HashSet<>());
12+
13+
// Observer that uses a background thread needlessly
14+
set.addObserver(new SetObserver<>() {
15+
public void added(ObservableSet<Integer> s, Integer e) {
16+
System.out.println(e);
17+
if (e == 23) {
18+
ExecutorService exec =
19+
Executors.newSingleThreadExecutor();
20+
try {
21+
exec.submit(() -> s.removeObserver(this)).get();
22+
} catch (ExecutionException | InterruptedException ex) {
23+
throw new AssertionError(ex);
24+
} finally {
25+
exec.shutdown();
26+
}
27+
}
28+
}
29+
});
30+
31+
for (int i = 0; i < 100; i++)
32+
set.add(i);
33+
}
34+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package effectivejava.chapter11.item81;
2+
import java.util.concurrent.*;
3+
4+
// Simple framework for timing concurrent execution 327
5+
public class ConcurrentTimer {
6+
private ConcurrentTimer() { } // Noninstantiable
7+
8+
public static long time(Executor executor, int concurrency,
9+
Runnable action) throws InterruptedException {
10+
CountDownLatch ready = new CountDownLatch(concurrency);
11+
CountDownLatch start = new CountDownLatch(1);
12+
CountDownLatch done = new CountDownLatch(concurrency);
13+
14+
for (int i = 0; i < concurrency; i++) {
15+
executor.execute(() -> {
16+
ready.countDown(); // Tell timer we're ready
17+
try {
18+
start.await(); // Wait till peers are ready
19+
action.run();
20+
} catch (InterruptedException e) {
21+
Thread.currentThread().interrupt();
22+
} finally {
23+
done.countDown(); // Tell timer we're done
24+
}
25+
});
26+
}
27+
28+
ready.await(); // Wait for all workers to be ready
29+
long startNanos = System.nanoTime();
30+
start.countDown(); // And they're off!
31+
done.await(); // Wait for all workers to finish
32+
return System.nanoTime() - startNanos;
33+
}
34+
}

0 commit comments

Comments
 (0)