|
2 | 2 | // (c)2017 MindView LLC: see Copyright.txt |
3 | 3 | // We make no guarantees that this code is fit for any purpose. |
4 | 4 | // Visit http://OnJava8.com for more book information. |
5 | | -// Operations that might seem safe are not, |
6 | | -// when threads are present. |
7 | | -import java.util.*; |
| 5 | +// Test SerialNumbers implementations for thread-safety |
8 | 6 | import java.util.concurrent.*; |
9 | 7 | import onjava.Nap; |
10 | 8 |
|
11 | | -// Reuses storage so we don't run out of memory: |
12 | | -class CircularSet { |
13 | | - private int[] array; |
14 | | - private int size; |
15 | | - private int index = 0; |
16 | | - public CircularSet(int size) { |
17 | | - array = new int[size]; |
18 | | - // Initialize to a value not produced |
19 | | - // by the SerialNumberSupplier: |
20 | | - Arrays.fill(array, -1); |
21 | | - this.size = size; |
22 | | - } |
23 | | - public synchronized void add(int i) { |
24 | | - array[index] = i; |
25 | | - // Wrap index and write over old elements: |
26 | | - index = ++index % size; |
27 | | - } |
28 | | - public synchronized boolean contains(int val) { |
29 | | - for(int i = 0; i < size; i++) |
30 | | - if(array[i] == val) return true; |
31 | | - return false; |
32 | | - } |
33 | | -} |
34 | | - |
35 | 9 | public class SerialNumberChecker implements Runnable { |
36 | 10 | private CircularSet serials = new CircularSet(1000); |
| 11 | + private SerialNumbers producer; |
| 12 | + public SerialNumberChecker(SerialNumbers producer) { |
| 13 | + this.producer = producer; |
| 14 | + } |
37 | 15 | @Override |
38 | 16 | public void run() { |
39 | 17 | while(true) { |
40 | | - int serial = |
41 | | - SerialNumberSupplier.nextSerialNumber(); |
| 18 | + int serial = producer.nextSerialNumber(); |
42 | 19 | if(serials.contains(serial)) { |
43 | 20 | System.out.println("Duplicate: " + serial); |
44 | 21 | System.exit(0); |
45 | 22 | } |
46 | 23 | serials.add(serial); |
47 | 24 | } |
48 | 25 | } |
49 | | - public static void main(String[] args) { |
| 26 | + static void test(SerialNumbers producer) { |
50 | 27 | for(int i = 0; i < 10; i++) |
51 | 28 | CompletableFuture.runAsync( |
52 | | - new SerialNumberChecker()); |
| 29 | + new SerialNumberChecker(producer)); |
53 | 30 | new Nap(4000, "No duplicates detected"); |
54 | 31 | } |
55 | 32 | } |
56 | | -/* Output: |
57 | | -Duplicate: 4119 |
58 | | -*/ |
0 commit comments