Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ «Ѐилософия Java3Β». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 122

Автор Π‘Ρ€ΡŽΡ ЭккСль

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.