1+ package concurrency ;
2+
3+ import java .util .ArrayList ;
4+ import java .util .Collections ;
5+ import java .util .List ;
6+ import java .util .concurrent .ExecutorService ;
7+ import java .util .concurrent .Executors ;
8+ import java .util .concurrent .TimeUnit ;
9+ import java .util .concurrent .atomic .AtomicInteger ;
10+ import java .util .concurrent .locks .Lock ;
11+ import java .util .concurrent .locks .ReentrantLock ;
12+
13+ /**
14+ * 临界区(同步代码块)学习
15+ *
16+ * @author :chenxin
17+ * @date :Created in 2020/3/16 20:44
18+ * @modified By:
19+ * @version: $
20+ */
21+ public class CriticalSection {
22+ static void testApproaches (PairManager pman1 , PairManager pman2 ) {
23+ ExecutorService executorService = Executors .newCachedThreadPool ();
24+ PairManipulator pm1 = new PairManipulator (pman1 );
25+ PairManipulator pm2 = new PairManipulator (pman2 );
26+ PairChecker pcheck1 = new PairChecker (pman1 );
27+ PairChecker pcheck2 = new PairChecker (pman2 );
28+ executorService .execute (pm1 );
29+ executorService .execute (pm2 );
30+ executorService .execute (pcheck1 );
31+ executorService .execute (pcheck2 );
32+ try {
33+ TimeUnit .MILLISECONDS .sleep (500 );
34+ } catch (InterruptedException e ) {
35+ System .out .println ("Sleep interrupted" );
36+ }
37+ System .out .println ("pm1: " + pm1 + "\n pm2: " + pm2 );
38+ System .exit (0 );
39+ }
40+
41+ public static void main (String [] args ) {
42+ PairManager1 pman1 = new PairManager1 ();
43+ PairManager2 pman2 = new PairManager2 ();
44+ testApproaches (pman1 , pman2 );
45+ }
46+ }
47+
48+ class Pair {
49+ private int x , y ;
50+
51+ public Pair (int x , int y ) {
52+ this .x = x ;
53+ this .y = y ;
54+ }
55+
56+ public Pair () {
57+ this (0 , 0 );
58+ }
59+
60+ public int getX () {
61+ return x ;
62+ }
63+
64+ public int getY () {
65+ return y ;
66+ }
67+
68+ public void incrementX () {
69+ x ++;
70+ }
71+
72+ public void incrementY () {
73+ y ++;
74+ }
75+
76+ @ Override
77+ public String toString () {
78+ return "x: " + x + ", y:" + y ;
79+ }
80+
81+ public class PairValuesNotEqualException extends RuntimeException {
82+ public PairValuesNotEqualException () {
83+ super ("Pair values not equal: " + Pair .this );
84+ }
85+ }
86+
87+ public void checkState () {
88+ if (x != y ) {
89+ throw new PairValuesNotEqualException ();
90+ }
91+ }
92+ }
93+
94+ abstract class PairManager {
95+ AtomicInteger checkCounter = new AtomicInteger (0 );
96+ protected Pair p = new Pair ();
97+ private List <Pair > storage = Collections .synchronizedList (new ArrayList <Pair >());
98+
99+ public synchronized Pair getPair () {
100+ return new Pair (p .getX (), p .getY ());
101+ }
102+
103+ protected void store (Pair p ) {
104+ storage .add (p );
105+ try {
106+ TimeUnit .MILLISECONDS .sleep (50 );
107+ } catch (InterruptedException e ) {
108+ }
109+
110+ }
111+
112+ public abstract void increment ();
113+ }
114+
115+ class PairManager1 extends PairManager {
116+
117+ @ Override
118+ public synchronized void increment () {
119+ p .incrementX ();
120+ p .incrementY ();
121+ store (getPair ());
122+ }
123+ }
124+
125+ class PairManager3 extends PairManager {
126+
127+ Lock lock = new ReentrantLock ();
128+
129+ @ Override
130+ public void increment () {
131+ Pair temp ;
132+ lock .lock ();
133+ try {
134+ p .incrementX ();
135+ p .incrementY ();
136+ temp = getPair ();
137+ } finally {
138+ lock .unlock ();
139+ }
140+ store (temp );
141+ }
142+ }
143+
144+ class PairManager2 extends PairManager {
145+
146+ @ Override
147+ public void increment () {
148+ Pair temp ;
149+ synchronized (this ) {
150+ p .incrementX ();
151+ p .incrementY ();
152+ temp = getPair ();
153+ }
154+ store (temp );
155+ }
156+ }
157+
158+ class PairManipulator implements Runnable {
159+ private PairManager pm ;
160+
161+ public PairManipulator (PairManager pm ) {
162+ this .pm = pm ;
163+ }
164+
165+ public void run () {
166+ while (true ) {
167+ pm .increment ();
168+ }
169+ }
170+
171+ @ Override
172+ public String toString () {
173+ return "Pair: " + pm .getPair () + " checkCounter = " + pm .checkCounter .get ();
174+ }
175+ }
176+
177+ class PairChecker implements Runnable {
178+ private PairManager pm ;
179+
180+ public PairChecker (PairManager pm ) {
181+ this .pm = pm ;
182+ }
183+
184+ public void run () {
185+ while (true ) {
186+ pm .checkCounter .incrementAndGet ();
187+ pm .getPair ().checkState ();
188+ }
189+ }
190+ }
0 commit comments