new CircularSet(lOOO); private static ExecutorService exec =
Executors.newCachedThreadPool(), static class SerialChecker implements Runnable { public void run() {
while(true) {
int serial =
Seri alNumberGenerator.nextSeri alNumber(); if(serials.contains(serial)) {
System, out. pri ntl nCDuplicate: " + serial); System.exit(O);
}
serials.add(serial);
}
}
}
public static void main(String[] args) throws Exception { for(int i = 0; i < SIZE, i++)
exec, execute (new SerialCheckerO); // ΠΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡΡ ΠΏΠΎΡΠ»Π΅ n ΡΠ΅ΠΊΡΠ½Π΄ ΠΏΡΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°:
if(args length > 0) {
TimeUnit SECONDS sleep(new lnteger(args[0])). System out printin("No duplicates detected"), System exit(0).
}
}
} /* Output Duplicate 8468656 *///β’-
Π ΠΊΠ»Π°ΡΡΠ΅ SerialNumberChecker ΡΠΎΠ΄Π΅ΡΠΆΠΈΡΡΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΎΠ΅ ΠΏΠΎΠ»Π΅ CircuLarSet, Ρ ΡΠ°Π½ΡΡΠ΅Π΅ Π²ΡΠ΅ ΡΠ΅ΡΠΈΠΉΠ½ΡΠ΅ Π½ΠΎΠΌΠ΅ΡΠ°, ΠΈ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΠΉ ΠΏΠΎΡΠΎΠΊ Thread, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ ΡΡΠΈ Π½ΠΎΠΌΠ΅ΡΠ° ΠΈ ΡΠ΄ΠΎΡΡΠΎΠ²Π΅ΡΡΠ΅ΡΡΡ Π² ΠΈΡ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΠΎΡΡΠΈ. Π‘ΠΎΠ·Π΄Π°Π² Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΡΠΎΠΊΠΎΠ², ΠΏΡΠ΅ΡΠ΅Π½Π΄ΡΡΡΠΈΡ Π½Π° ΡΠ΅ΡΠΈΠΉΠ½ΡΠ΅ Π½ΠΎΠΌΠ΅ΡΠ°, Π²Ρ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΡΠ΅, ΡΡΠΎ ΠΊΠ°ΠΊΠΎΠΉ-Π½ΠΈΠ±ΡΠ΄Ρ ΠΈΠ· Π½ΠΈΡ Π΄ΠΎΠ²ΠΎΠ»ΡΠ½ΠΎ Π±ΡΡΡΡΠΎ ΠΏΠΎΠ»ΡΡΠΈΡ ΡΠΆΠ΅ ΠΈΠΌΠ΅ΡΡΠΈΠΉΡΡ Π½ΠΎΠΌΠ΅Ρ (Π·Π°ΠΌΠ΅ΡΡΡΠ΅, ΡΡΠΎ Π½Π° Π²Π°ΡΠ΅ΠΉ ΠΌΠ°ΡΠΈΠ½Π΅ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° ΠΌΠΎΠΆΠ΅Ρ ΠΈ Π½Π΅ ΠΎΠ±Π½Π°ΡΡΠΆΠΈΡΡ ΠΊΠΎΠ½ΡΠ»ΠΈΠΊΡ, Π½ΠΎ Π½Π° ΠΌΠ½ΠΎΠ³ΠΎΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ½ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΠ΅ ΠΎΠ½Π° ΡΡΠΏΠ΅ΡΠ½ΠΎ ΠΈΡ Π½Π°ΡΠ»Π°). ΠΠ»Ρ ΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌΡ Π΄ΠΎΠ±Π°Π²ΡΡΠ΅ ΠΊ ΠΌΠ΅ΡΠΎΠ΄Ρ nextSe-rialNumber() ΡΠ»ΠΎΠ²ΠΎ synchronized.
ΠΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ, ΡΡΠΎ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡΠΌΠΈ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΠΌΠΈ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡΠΌΠΈ ΡΠ²Π»ΡΡΡΡΡ ΡΡΠ΅Π½ΠΈΠ΅ ΠΈ ΠΏΡΠΈΡΠ²ΠΎΠ΅Π½ΠΈΠ΅ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²ΠΎΠ². ΠΠ΄Π½Π°ΠΊΠΎ, ΠΊΠ°ΠΊ ΠΌΡ ΡΠ²ΠΈΠ΄Π΅Π»ΠΈ Π² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ Atomi-cityTest.java, Π²ΡΠ΅ ΡΠ°ΠΊ ΠΆΠ΅ ΠΏΡΠΎΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π΄Π»Ρ ΠΎΠ±ΡΠ΅ΠΊΡΠ°, ΠΊΠΎΡΠΎΡΡΠΉ Π½Π°Ρ ΠΎΠ΄ΠΈΡΡΡ Π² Π½Π΅ΡΡΠ°Π±ΠΈΠ»ΡΠ½ΠΎΠΌ ΠΏΡΠΎΠΌΠ΅ΠΆΡΡΠΎΡΠ½ΠΎΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΠΈ, ΡΠ°ΠΊ ΡΡΠΎ ΠΎΠΆΠΈΠ΄Π°ΡΡ, ΡΡΠΎ ΠΊΠ°ΠΊΠΈΠ΅-ΡΠΎ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΎΠΏΡΠ°Π²Π΄Π°ΡΡΡΡ, ΠΎΠΏΠ°ΡΠ½ΠΎ ΠΈ Π½Π΅Π½Π°Π΄Π΅ΠΆΠ½ΠΎ.
ΠΡΠΎΠΌΠ°ΡΠ½ΡΠ΅ ΠΊΠ»Π°ΡΡΡ
Π Java SE5 ΠΏΠΎΡΠ²ΠΈΠ»ΠΈΡΡ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΠ΅ ΠΊΠ»Π°ΡΡΡ Π΄Π»Ρ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ Ρ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΌΠΈ β Atomiclnteger, AtomicLong, AtomicReference ΠΈ Ρ. Π΄. ΠΡΠΈ ΠΊΠ»Π°ΡΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠ°Ρ Π°ΡΠΎΠΌΠ°ΡΠ½ΡΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ ΡΡΠ»ΠΎΠ²Π½ΠΎΠ³ΠΎ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΡ Π² ΡΠΎΡΠΌΠ΅
boolean compareAndSer(expectedValue, updateValue),
ΠΡΠΈ ΠΊΠ»Π°ΡΡΡ ΠΏΡΠ΅Π΄Π½Π°Π·Π½Π°ΡΠ΅Π½Ρ Π΄Π»Ρ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ Ρ ΡΠ΅Π»ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ Π°ΡΠΎΠΌΠ°ΡΠ½ΠΎΡΡΠΈ Π½Π° ΠΌΠ°ΡΠΈΠ½Π½ΠΎΠΌ ΡΡΠΎΠ²Π½Π΅ Π½Π° Π½Π΅ΠΊΠΎΡΠΎΡΡΡ ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ°Ρ , ΠΏΠΎΡΡΠΎΠΌΡ Π² ΠΎΠ±ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ Π²Π°ΠΌ ΠΎΠ½ΠΈ Π½Π΅ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΡΡΡΡ. ΠΠ½ΠΎΠ³Π΄Π° ΠΎΠ½ΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡΡΡ ΠΈ Π² ΠΏΠΎΠ²ΡΠ΅Π΄Π½Π΅Π²Π½ΠΎΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠΈΡΠΎΠ²Π°Π½ΠΈΠΈ, Π½ΠΎ ΡΠΎΠ»ΡΠΊΠΎ ΠΏΡΠΈ ΠΎΠΏΡΠΈΠΌΠΈΠ·Π°ΡΠΈΠΈ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π²Π΅ΡΡΠΈΡ AtomicityTest.java, ΠΏΠ΅ΡΠ΅ΠΏΠΈΡΠ°Π½Π½Π°Ρ Π΄Π»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ Atomic-Integer, Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΡΠ°ΠΊ:
// concurrency/AtomicIntegerTest java import java.util concurrent *. import java util concurrent atomic *; import java.util.*.
public class AtomicIntegerTest implements Runnable { private Atomiclnteger i = new AtomicInteger(O), public int getValueO { return i getO. } private void evenIncrement() { i addAndGet(2), } public void runΠ { while(true)
evenlncrement();
}
public static void main(String[] args) { ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ &
new TimerO.schedule(new TimerTaskO { public void run() {
System.err println("Aborting"). System exit(O).
}
}, 5000). // ΠΠ°Π²Π΅ΡΡΠ΅Π½ΠΈΠ΅ ΡΠ΅ΡΠ΅Π· 5 ΡΠ΅ΠΊΡΠ½Π΄ ExecutorService exec = Executors newCachedThreadPoolO. Atomic I ntegerTest ait = new AtomicIntegerTestO; exec.execute(ait); while(true) {
int val = ait getValueO. if(val % 2 != 0) {
System out.println(val); System.exit(0);
}
}
}
} ///:-
ΠΠ΄Π΅ΡΡ Π²ΠΌΠ΅ΡΡΠΎ ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ³ΠΎ ΡΠ»ΠΎΠ²Π° synchronized ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Atomiclnteger. Π’Π°ΠΊ ΠΊΠ°ΠΊ ΡΠ±ΠΎΠΉ Π² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅ Π½Π΅ ΠΏΡΠΎΠΈΡΡ ΠΎΠ΄ΠΈΡ, Π² ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ Π²ΠΊΠ»ΡΡΠ°Π΅ΡΡΡ ΡΠ°ΠΉΠΌΠ΅Ρ, Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ Π·Π°Π²Π΅ΡΡΠ°ΡΡΠΈΠΉ Π΅Π΅ ΡΠ΅ΡΠ΅Π· 5 ΡΠ΅ΠΊΡΠ½Π΄.
ΠΠΎΡ ΠΊΠ°ΠΊ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΠΏΡΠΈΠΌΠ΅Ρ MutexEvenGeneratorjava, ΠΏΠ΅ΡΠ΅ΠΏΠΈΡΠ°Π½Π½ΡΠΉ Π΄Π»Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ ΠΊΠ»Π°ΡΡΠ° Atomiclnteger:
//: concurrency/AtomicEvenGenerator.java
// ΠΡΠΎΠΌΠ°ΡΠ½ΡΠ΅ ΠΊΠ»Π°ΡΡΡ ΠΈΠ½ΠΎΠ³Π΄Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ Π² ΠΎΠ±ΡΡΠ½ΠΎΠΌ ΠΊΠΎΠ΄Π΅.
// {RunByHand}
import java.util.concurrent.atomic.*;
public class AtomicEvenGenerator extends IntGenerator { private Atomiclnteger currentEvenValue =
new AtomiΡInteger(0); public int nextO {
return currentEvenValue.addAndGet(2);
}
public static void main(String[] args) {
EvenChecker.test(new AtomicEvenGeneratorO);
}
} ///.-
Π‘ΡΠΎΠΈΡ Π΅ΡΠ΅ ΡΠ°Π· ΠΏΠΎΠ΄ΡΠ΅ΡΠΊΠ½ΡΡΡ, ΡΡΠΎ ΠΊΠ»Π°ΡΡΡ Atomic ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π»ΠΈΡΡ Π΄Π»Ρ ΠΏΠΎΡΡΡΠΎΠ΅Π½ΠΈΡ ΠΊΠ»Π°ΡΡΠΎΠ² ΠΈΠ· java.util.concurrent. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΠΈΡ Π² ΡΠ²ΠΎΠΈΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°Ρ ΡΠΎΠ»ΡΠΊΠΎ Π² ΠΎΡΠΎΠ±ΡΡ ΡΠ»ΡΡΠ°ΡΡ ΠΈ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΎΠ³Π΄Π°, ΠΊΠΎΠ³Π΄Π° Π²Ρ ΡΠ²Π΅ΡΠ΄ΠΎ ΡΠ²Π΅ΡΠ΅Π½Ρ, ΡΡΠΎ ΡΡΠΎ Π½Π΅ ΡΠΎΠ·Π΄Π°ΡΡ Π½ΠΎΠ²ΡΡ ΠΏΡΠΎΠ±Π»Π΅ΠΌ. Π ΠΎΠ±ΡΠ΅ΠΌ ΡΠ»ΡΡΠ°Π΅ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½Π΅Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ (Ρ ΠΊΠ»ΡΡΠ΅Π²ΡΠΌ ΡΠ»ΠΎΠ²ΠΎΠΌ synchronized ΠΈΠ»ΠΈ ΡΠ²Π½ΡΠΌ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ΠΌ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Lock).
ΠΡΠΈΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ΅ΠΊΡΠΈΠΈ
ΠΠ½ΠΎΠ³Π΄Π° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΡΠ΅Π΄ΠΎΡΠ²ΡΠ°ΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² ΡΠΎΠ»ΡΠΊΠΎ ΠΊ ΡΠ°ΡΡΠΈ ΠΊΠΎΠ΄Π°, Π° Π½Π΅ ΠΊ ΠΌΠ΅ΡΠΎΠ΄Ρ Π² ΡΠ΅Π»ΠΎΠΌ. Π€ΡΠ°Π³ΠΌΠ΅Π½Ρ ΠΊΠΎΠ΄Π°, ΠΊΠΎΡΠΎΡΡΠΉ ΠΈΠ·ΠΎΠ»ΠΈΡΡΠ΅ΡΡΡ ΡΠ°ΠΊΠΈΠΌ ΡΠΏΠΎΡΠΎΠ±ΠΎΠΌ, Π½Π°Π·ΡΠ²Π°Π΅ΡΡΡ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΡΠ΅ΠΊΡΠΈΠ΅ΠΉ (critical section), Π΄Π»Ρ Π΅Π³ΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΠ°ΠΊΠΆΠ΅ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΡΡΡ ΠΊΠ»ΡΡΠ΅Π²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ synchronized. ΠΠ° ΡΡΠΎΡ ΡΠ°Π· ΡΠ»ΠΎΠ²ΠΎ synchronized ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡ, Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ° ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π΄ΠΎΠ»ΠΆΠ½Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π΄Π»Ρ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΠ° ΠΊΠΎΠ΄Π°:
5ΡΠΏΡΠΠ³ΠΎΠΏ12Π΅Ρ1(ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΡΠ΅ΠΌΡΠΉ0Π±ΡΠ΅ΠΊΡ) {
//Π ΡΠ°ΠΊΠΎΠΌΡ ΠΊΠΎΠ΄Ρ Π΄ΠΎΡΡΡΠΏ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ // ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΡΠΎΠΊ
}
Π’Π°ΠΊΠ°Ρ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΈΡ ΠΈΠ½Π°ΡΠ΅ Π½Π°Π·ΡΠ²Π°Π΅ΡΡΡ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΎΠΉ (synchronized block); ΠΏΠ΅ΡΠ΅Π΄ Π²Ρ ΠΎΠ΄ΠΎΠΌ Π² Π½Π΅Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ Π΄Π»Ρ syncObject. ΠΡΠ»ΠΈ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ° ΡΠΆΠ΅ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»Π΅Π½Π° Π΄ΡΡΠ³ΠΎΠΌΡ ΠΏΠΎΡΠΎΠΊΡ, Π²Ρ ΠΎΠ΄ Π² ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠΈΠΉ ΡΡΠ°Π³ΠΌΠ΅Π½Ρ ΠΊΠΎΠ΄Π° Π·Π°ΠΏΡΠ΅ΡΠ°Π΅ΡΡΡ Π΄ΠΎ ΡΠ΅Ρ ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠ° Π½Π΅ Π±ΡΠ΄Π΅Ρ ΡΠ½ΡΡΠ°.
Π‘Π»Π΅Π΄ΡΡΡΠΈΠΉ ΠΏΡΠΈΠΌΠ΅Ρ ΡΡΠ°Π²Π½ΠΈΠ²Π°Π΅Ρ Π΄Π²Π° ΠΏΠΎΠ΄Ρ ΠΎΠ΄Π° ΠΊ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ, ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Ρ, Π½Π°ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅ΡΡΡ Π²ΡΠ΅ΠΌΡ, ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅ΠΌΠΎΠ΅ ΠΏΠΎΡΠΎΠΊΠ°ΠΌ Π΄Π»Ρ Π΄ΠΎΡΡΡΠΏΠ° ΠΊ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ Π²ΠΌΠ΅ΡΡΠΎ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ². ΠΠ΄ΠΎΠ±Π°Π²ΠΎΠΊ ΠΎΠ½ Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΠ΅Ρ, ΠΊΠ°ΠΊ Π½Π΅Π·Π°ΡΠΈΡΠ΅Π½Π½ΡΠΉ ΠΊΠ»Π°ΡΡ ΠΌΠΎΠΆΠ΅Ρ Β«Π²ΡΠΆΠΈΡΡΒ» Π² ΠΌΠ½ΠΎΠ³ΠΎΠ·Π°Π΄Π°ΡΠ½ΠΎΠΉ ΡΡΠ΅Π΄Π΅, Π΅ΡΠ»ΠΈ ΠΎΠ½ ΡΠΏΡΠ°Π²Π»ΡΠ΅ΡΡΡ ΠΈ Π·Π°ΡΠΈΡΠ°Π΅ΡΡΡ Π΄ΡΡΠ³ΠΈΠΌ ΠΊΠ»Π°ΡΡΠΎΠΌ:
//: concurrency/CriticalSection.java
// Π‘ΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ Π±Π»ΠΎΠΊΠΎΠ² Π²ΠΌΠ΅ΡΡΠΎ ΡΠ΅Π»ΡΡ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ². Π’Π°ΠΊΠΆΠ΅ Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠΈΡΡΠ΅Ρ Π·Π°ΡΠΈΡΡ
// Π½Π΅ΠΏΡΠΈΡΠΏΠΎΡΠΎΠ±Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΊ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΡΡΠΈ ΠΊΠ»Π°ΡΡΠ° Π΄ΡΡΠ³ΠΈΠΌ ΠΊΠ»Π°ΡΡΠΎΠΌ
package concurrency;
import java.util.concurrent.*:
import java.util.concurrent.atomic.*;
import java.util.*;
class Pair { // Not thread-safe private int x, y; public Pair(int x. int y) { this.x = x; this.Ρ = Ρ;
}
public PairO { this(0, 0); } public int getXO { return x; } public int getYO { return y; } public void incrementXO { x++; } public void incrementYO { y++; } public String toStringO {
return "x; " + x + ", y; " + y;
}
public class PairValuesNotEqualException extends RuntimeException {
public Pai rValuesNotEqual Excepti onO {
superC'Pair values not equal; " + Pair.this);
}
}
// ΠΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΡΠΉ ΠΈΠ½Π²Π°ΡΠΈΠ°Π½Ρ - ΠΎΠ±Π΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ Π±ΡΡΡ ΡΠ°Π²Π½Ρ; public void checkStateO { if(x != Ρ)
throw new PairValuesNotEqualException();
}
}
// ΠΠ°ΡΠΈΡΠ° ΠΊΠ»Π°ΡΡΠ° Pair Π²Π½ΡΡΡΠΈ ΠΏΡΠΈΡΠΏΠΎΡΠΎΠ±Π»Π΅Π½Π½ΠΎΠ³ΠΎ ΠΊ ΠΏΠΎΡΠΎΠΊΠ°ΠΌ ΠΊΠ»Π°ΡΡΠ°; abstract class PairManager {
Atomiclnteger checkCounter = new AtomicInteger(O). protected Pair p = new PairO. private List<Pair> storage =
Collections synchronizedList(new ArrayList<Pair>0). public synchronized Pair getPairO {
// Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ ΠΊΠΎΠΏΠΈΡ, ΡΡΠΎΠ±Ρ ΡΠΎΡ ΡΠ°Π½ΠΈΡΡ ΠΎΡΠΈΠ³ΠΈΠ½Π°Π» Π² Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ return new Pair(p getXO, p getYO).
}
// ΠΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ, ΡΡΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ΅ Π²ΡΠ΅ΠΌΡ protected void store(Pair Ρ) { storage add(p), try {
TimeUnit MILLISECONDS sleep(50); } catch(InterruptedException ignore) {}
}
public abstract void incrementO.
}
// Π‘ΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ Π²ΡΠ΅Π³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π°.
class PairManagerl extends PairManager { public synchronized void incrementO { p.incrementXO. p incrementYO. store(getPairO).
// ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΡΠ΅ΠΊΡΠΈΠΈ-class PairManager2 extends PairManager { public void incrementO { Pair temp.
synchronized(this) {
p incrementXO; p. incrementYO; temp = getPairO,
}
store(temp).
class PairManipulator implements Runnable { private PairManager pm; public PairManipulator(PairManager pm) { this pm = pm,
}
public void run Π { while(true)
pm. increment);
}
public String toStringO {
return "Pair: " + pm.getPairO +
" checkCounter = " + pm checkCounter.get Π;
}
}
class PairChecker implements Runnable { private PairManager pm; public PairChecker(PairManager pm) {
}
public class CriticalSection { // Π‘ΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ Π΄Π²ΡΡ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ΠΎΠ²-static void
testApproaches(PairManager pmanl. PairManager pman2) {
ExecutorService exec = Executors newCachedThreadPool(). PairManipulator
pml = new PairManipulator(pmanl), pm2 = new PairManipulator(pman2), PairChecker
pcheckl = new PairChecker(pmanl), pcheck2 = new PairChecker(pman2), exec execute(pml), exec execute(pm2), exec execute(pcheckl); exec execute(pcheck2), try {
TimeUnit MILLISECONDS sleep(500); } catchdnterruptedException e) {
System out.printlnC'Sleep interrupted"),
}
System.out printin("pml " + pml + "\npm2: " + pm2). System exit(O),
}
public static void main(String[] args) { PairManager
pmanl = new PairManagerlO, pman2 = new PairManager2(); testApproaches(pmanl. pman2);
}
} /* Output-
pml- Pair. x. 15, Ρ 15 checkCounter = 272565 pm2- Pair- x. 16, y: 16 checkCounter = 3956974 */// ~
ΠΠ°ΠΊ Π±ΡΠ»ΠΎ ΠΎΡΠΌΠ΅ΡΠ΅Π½ΠΎ, ΠΊΠ»Π°ΡΡ Pair Π½Π΅ ΠΏΡΠΈΡΠΏΠΎΡΠΎΠ±Π»Π΅Π½ ΠΊ ΡΠ°Π±ΠΎΡΠ΅ Ρ ΠΏΠΎΡΠΎΠΊΠ°ΠΌΠΈ, ΠΏΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π΅Π³ΠΎ ΠΈΠ½Π²Π°ΡΠΈΠ°Π½Ρ (ΠΏΡΠ΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΡΠΉ) ΡΡΠ΅Π±ΡΠ΅Ρ ΡΠ°Π²Π΅Π½ΡΡΠ²Π° ΠΎΠ±ΠΎΠΈΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ . ΠΠ΄ΠΎΠ±Π°Π²ΠΎΠΊ, ΠΊΠ°ΠΊ ΠΌΡ ΡΠΆΠ΅ Π²ΠΈΠ΄Π΅Π»ΠΈ Π² ΡΡΠΎΠΉ Π³Π»Π°Π²Π΅, ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΈΠ½ΠΊΡΠ΅ΠΌΠ΅Π½ΡΠ° Π½Π΅Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½Ρ Π² ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠΈ ΠΊ ΠΏΠΎΡΠΎΠΊΠ°ΠΌ, ΠΈ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ Π½ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² Π½Π΅ Π±ΡΠ» ΠΎΠ±ΡΡΠ²Π»Π΅Π½ ΠΊΠ°ΠΊ synchronized, ΠΌΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΡΡΠΈΡΠ°ΡΡ, ΡΡΠΎ ΠΎΠ±ΡΠ΅ΠΊΡ Pair ΠΎΡΡΠ°Π½Π΅ΡΡΡ Π½Π΅ΠΏΠΎΠ²ΡΠ΅ΠΆΠ΄Π΅Π½Π½ΡΠΌ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ΅.
ΠΡΠ΅Π΄ΡΡΠ°Π²ΡΡΠ΅, ΡΡΠΎ Π²Ρ ΠΏΠΎΠ»ΡΡΠΈΠ»ΠΈ Π³ΠΎΡΠΎΠ²ΡΠΉ ΠΊΠ»Π°ΡΡ Pair, ΠΊΠΎΡΠΎΡΡΠΉ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡΠ°Π±ΠΎΡΠ°ΡΡ Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡΠΎΡΠ½ΡΡ ΡΡΠ»ΠΎΠ²ΠΈΡΡ . ΠΠ»Π°ΡΡ PairManager Ρ ΡΠ°Π½ΠΈΡ ΠΎΠ±ΡΠ΅ΠΊΡΡ Pair ΠΈ ΡΠΏΡΠ°Π²Π»ΡΠ΅Ρ Π»ΡΠ±ΡΠΌ Π΄ΠΎΡΡΡΠΏΠΎΠΌ ΠΊ Π½ΠΈΠΌ. ΠΠ°ΠΌΠ΅ΡΡΡΠ΅, ΡΡΠΎ Π΅Π΄ΠΈΠ½ΡΡΠ²Π΅Π½Π½ΡΠΌΠΈ ΠΎΡΠΊΡΡΡΡΠΌΠΈ (public) ΠΌΠ΅ΡΠΎΠ΄Π°ΠΌΠΈ ΡΠ²Π»ΡΡΡΡΡ getPair(), ΠΎΠ±ΡΡΠ²Π»Π΅Π½Π½ΡΠΉ ΠΊΠ°ΠΊ synchronized, ΠΈ Π°Π±ΡΡΡΠ°ΠΊΡΠ½ΡΠΉ ΠΌΠ΅ΡΠΎΠ΄ doTask(). Π‘ΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ ΡΡΠΎΠ³ΠΎ ΠΌΠ΅ΡΠΎΠ΄Π° Π±ΡΠ΄Π΅Ρ ΠΎΡΡΡΠ΅ΡΡΠ²Π»Π΅Π½Π° ΠΏΡΠΈ Π΅Π³ΠΎ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ.
this pm = pm.
}
public void run() {
while(true) {
pm checkCounter.i ncrementAndGet(); pm getPa>r() checkState(),
Π‘ΡΡΡΠΊΡΡΡΠ° ΠΊΠ»Π°ΡΡΠ° PairManager, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΡΠ°ΡΡΡ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΠΈ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ ΠΊΠ»Π°ΡΡΠ° ΡΠ΅Π°Π»ΠΈΠ·ΡΠ΅ΡΡΡ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΠΌΠΈ Π°Π±ΡΡΡΠ°ΠΊΡΠ½ΡΠΌΠΈ ΠΌΠ΅ΡΠΎΠ΄Π°ΠΌΠΈ, ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠΌΠΈ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄Π½ΡΠΌΠΈ ΠΊΠ»Π°ΡΡΠ°ΠΌΠΈ, Π½Π°Π·ΡΠ²Π°Π΅ΡΡΡ Π½Π° ΡΠ·ΡΠΊΠ΅ ΠΏΠ°ΡΡΠ΅ΡΠ½ΠΎΠ² ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ Β«ΡΠ°Π±Π»ΠΎΠ½Π½ΡΠΌ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠΌΒ». ΠΠ°ΡΡΠ΅ΡΠ½Ρ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ ΠΈΠ½ΠΊΠ°ΠΏΡΡΠ»ΠΈΡΠΎΠ²Π°ΡΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π² ΠΊΠΎΠ΄Π΅ β Π·Π΄Π΅ΡΡ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡΠ°ΡΡΡ ΡΠ°ΡΡΡ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½Π° ΠΌΠ΅ΡΠΎΠ΄ΠΎΠΌ increment(). Π ΠΊΠ»Π°ΡΡΠ΅ PairManagerl ΠΌΠ΅ΡΠΎΠ΄ increment() ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½, Π² ΡΠΎ Π²ΡΠ΅ΠΌΡ ΠΊΠ°ΠΊ Π² ΠΊΠ»Π°ΡΡΠ΅ PairManager2 ΡΠΎΠ»ΡΠΊΠΎ ΡΠ°ΡΡΡ Π΅Π³ΠΎ Π±ΡΠ»Π° ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π° ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²ΠΎΠΌ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΡΠ΅ΠΌΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΠΈ. ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π΅ΡΠ΅ ΡΠ°Π·, ΡΡΠΎ ΠΊΠ»ΡΡΠ΅Π²ΡΠ΅ ΡΠ»ΠΎΠ²Π° synchronized Π½Π΅ ΡΠ²Π»ΡΡΡΡΡ ΡΠ°ΡΡΡΡ ΡΠΈΠ³Π½Π°ΡΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° ΠΈ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½Ρ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ.
ΠΠ΅ΡΠΎΠ΄ store() Π΄ΠΎΠ±Π°Π²Π»ΡΠ΅Ρ ΠΎΠ±ΡΠ΅ΠΊΡ Pair Π² ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Array-List, ΠΏΠΎΡΡΠΎΠΌΡ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΡ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ²ΠΎ-Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΠΉ. Π‘Π»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ, Π² Π·Π°ΡΠΈΡΠ΅ ΠΎΠ½ Π½Π΅ Π½ΡΠΆΠ΄Π°Π΅ΡΡΡ, ΠΏΠΎΡΡΠΎΠΌΡ Π΅Π³ΠΎ Π²ΡΠ·ΠΎΠ² ΡΠ°Π·ΠΌΠ΅ΡΠ΅Π½ Π·Π° ΠΏΡΠ΅Π΄Π΅Π»Π°ΠΌΠΈ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·ΠΈΡΡΠ΅ΠΌΠΎΠ³ΠΎ Π±Π»ΠΎΠΊΠ°.
ΠΠ»Π°ΡΡ PairManipulator ΡΠΎΠ·Π΄Π°Π΅ΡΡΡ Π΄Π»Ρ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π΄Π²ΡΡ ΡΠ°Π·Π½ΠΎΠ²ΠΈΠ΄Π½ΠΎΡΡΠ΅ΠΉ Pair-Manager: ΠΌΠ΅ΡΠΎΠ΄ increment() Π²ΡΠ·ΡΠ²Π°Π΅ΡΡΡ Π² Π·Π°Π΄Π°ΡΠ΅ Π² ΡΠΎ Π²ΡΠ΅ΠΌΡ, ΠΊΠ°ΠΊ Π² Π΄ΡΡΠ³ΠΎΠΉ Π·Π°Π΄Π°ΡΠ΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ PairChecker. ΠΠ΅ΡΠΎΠ΄ main() ΡΠΎΠ·Π΄Π°Π΅Ρ Π΄Π²Π° ΠΎΠ±ΡΠ΅ΠΊΡΠ° PairManipulator ΠΈ Π΄Π°Π΅Ρ ΠΈΠΌ ΠΏΠΎΡΠ°Π±ΠΎΡΠ°ΡΡ Π² ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π½Π΅ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, ΠΏΠΎΡΠ»Π΅ ΡΠ΅Π³ΠΎ Π²ΡΠ²ΠΎΠ΄ΡΡΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ ΠΏΠΎ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡ PairManipulator.