-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathSynchronizingDataAccess.java
160 lines (142 loc) · 4.03 KB
/
SynchronizingDataAccess.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package concurrency;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
/**
*
* @author chengfeili
* Jun 24, 2017 8:17:32 PM
*
* thread safety is the property of an object that guarantees safe
* execution by multiple threads at the same time. Now that we have
* multiple threads capable of accessing the same objects in memory, we
* have to make sure to organize our access to this data such that we
* don’t end up with invalid or unexpected results. Since threads run in
* a shared environment and memory space, how do we prevent two threads
* from interfering with each other?
*/
public class SynchronizingDataAccess {
/**
* Atomic is the property of an operation to be carried out as a single unit
* of execution without any interference by another thread.
*
* Unlike our previous sample output, the numbers 1 through 10 will always
* be output.
*
* 2 3 1 4 5 6 7 8 9 10
*
* 1 4 3 2 5 6 7 8 9 10
*
* 1 4 3 5 6 2 7 8 10 9
*/
private AtomicInteger sheepCount = new AtomicInteger(0);
private void incrementAndReport() {
System.out.print(sheepCount.incrementAndGet() + " ");
}
/**
* Synchronizing Methods
*
* We can add the synchronized modifier to any instance method to
* synchronize automatically on the object itself
* the following two method definitions are equivalent:
*/
/**
private void incrementAndReport1() {
synchronized (this) {
System.out.print((++sheepCount) + " ");
}
}
private synchronized void incrementAndReport2() {
System.out.print((++sheepCount) + " ");
}
*/
/**
public static void printDaysWork() {
synchronized (SheepManager.class) {
System.out.print("Finished work");
}
}
public static synchronized void printDaysWork() {
System.out.print("Finished work");
}
*/
/**
* While multi-threaded programming is about doing multiple things at the
* same time, synchronization is about taking multiple threads and making
* them perform in a more single-threaded manner.
*
* Synchronization is about protecting data integrity at the cost of performance.
*/
public void costOfSynchronization() {
}
}
/**
*
* A problem occurs when two threads both execute the right side of the
* expression, reading the “old” value before either thread writes the “new”
* value of the variable
*
* the unexpected result of two tasks executing at the same time is referred to
* as a race condition.
*
* 1 2 2 3 4 5 6 7 8 9
*
* 2 4 5 6 7 8 1 9 10 3
*
* 2 1 3 4 5 6 7 8 9 10
*
*
*/
class SheepManager {
private int sheepCount = 0;
void incrementAndReport() {
System.out.print((++sheepCount) + " ");
}
public static void main(String[] args) {
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(20);
SheepManager manager = new SheepManager();
for (int i = 0; i < 10; i++)
service.submit(() -> manager.incrementAndReport());
} finally {
if (service != null)
service.shutdown();
}
}
}
/**
* Improving Access with Synchronized Blocks
*
* The most common technique is to use a monitor, also called a lock, to
* synchronize access. A monitor is a structure that supports mutual exclusion
* or the property that at most one thread is executing a particular segment of
* code at a given time.
*
*
* This example is referred to as a synchronized block. Each thread that arrives
* will first check if any threads are in the block.
*
* 1 2 3 4 5 6 7 8 9 10
*
*/
class SheepManager2 {
private int sheepCount = 0;
private void incrementAndReport() {
synchronized (this) {
System.out.print((++sheepCount) + " ");
}
}
public static void main(String[] args) {
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(20);
SheepManager2 manager = new SheepManager2();
for (int i = 0; i < 10; i++)
service.submit(() -> manager.incrementAndReport());
} finally {
if (service != null)
service.shutdown();
}
}
}