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

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

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

Для создания критичСских сСкций Ρ‚Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ явно созданными ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ Lock:

//: concurrency/ExplicitCriticalSection.java

// ИспользованиС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Lock для создания критичСских сСкций.

package concurrency;

import java.util.concurrent.locks.*;

// Бинхронизация Ρ†Π΅Π»ΠΎΠ³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°: class ExplicitPairManagerl extends PairManager { private Lock lock = new ReentrantLockO; public synchronized void incrementO { lock lockO; try {

p.incrementXO; p. incrementYO; store(getPairO); } finally {

lock.unlock О;

}

}

}

// ИспользованиС критичСской сСкции: class ExplicitPairManager2 extends PairManager { private Lock lock = new ReentrantLockO: public void incrementO { Pair temp; lock.lockO: try {

p.incrementXO;

Ρ€ incrementYO. temp = getPairO. } finally {

lock unlock О,

}

store(temp),

public class ExplicitCriticalSection {

public static void main(String[] args) throws Exception { PairManager

pmanl = new ExplicitPairManagerK), pman2 = new ExplicitPairManager2(), CriticalSection.testApproaches(pmanl, pman2);

}

} /* Output

pml. Pair: x: 15, Ρƒ 15 checkCounter = 174035 pm2: Pair- x- 16, Ρƒ 16 checkCounter = 2608588 *///.-

Π’ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ Π½ΠΎΠ²Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ PairManager с явным использованиСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Lock. ExplicitPairManager2 дСмонстрируСт созданиС критичСской сСкции с использованиСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Lock; Π²Ρ‹Π·ΠΎΠ² store() находится Π²Π½Π΅ критичСской сСкции.

Бинхронизация ΠΏΠΎ Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ

Π‘Π»ΠΎΠΊΡƒ synchronized Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π±ΡƒΠ΄Π΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ для синхронизации. Π§Π°Ρ‰Π΅ всСго Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ СстСствСнно ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, для ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π±Ρ‹Π» Π²Ρ‹Π·Π²Π°Π½ ΠΌΠ΅Ρ‚ΠΎΠ΄ synchronized(this), ΠΈ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚Π°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ Π² классС PairManager2. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΏΡ€ΠΈ Π²Ρ…ΠΎΠ΄Π΅ Π² синхронизируСмый Π±Π»ΠΎΠΊ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ синхронизированныС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Π±ΡƒΠ΄Π΅Ρ‚ нСльзя. ДСйствиС синхронизации ΠΏΠΎ this фактичСски Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² суТСнии области синхронизации.

Иногда Π²Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ Ρ‡Ρ‚ΠΎ-Ρ‚ΠΎ ΠΈΠ½ΠΎΠ΅, ΠΈ Π² Ρ‚Π°ΠΊΠΈΡ… ситуациях Π²Ρ‹ создаСтС ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ΠΈ выполняСтС ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ, привлСкая Π΅Π³ΠΎ. Π’ Ρ‚Π°ΠΊΠΈΡ… случаях Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΏΠΎΠ·Π°Π±ΠΎΡ‚ΠΈΡ‚ΡŒΡΡ ΠΎ Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ всС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π»ΠΈΡΡŒ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ ΠΈ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚, ΠΊΠ°ΠΊ Π΄Π²Π° ΠΏΠΎΡ‚ΠΎΠΊΠ° входят Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΠ³Π΄Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ этого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° синхронизированы Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°ΠΌΠΈ:

Π£/ concurrency/SyncObject java // Бинхронизация ΠΏΠΎ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ, import static net.mindview util.Print *;

class Dual Synch {

private Object syncObject = new Object О; public synchronized void f() {

for(int i = 0; i < 5; i++) { printCfO"); Thread.yieldO;

}

}

public void gO { ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΠ΅ &

synchronizedsyncObject) {

for(int i = 0; i < 5; i++) { printC'gO"); Thread.yieldO;

public class SyncObject {

public static void main(String[] args) {

final Dual Synch ds = new DualSynchO; new ThreadO {

public void run() { ds.fO;

}

}.startO; ds.gO;

}

} /* Output:

go

fO

go f() go fo go fo go f() *///:-

ΠœΠ΅Ρ‚ΠΎΠ΄ f() класса DualSync синхронизируСтся ΠΏΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ this (синхронизируя ΠΌΠ΅Ρ‚ΠΎΠ΄ Ρ†Π΅Π»ΠΈΠΊΠΎΠΌ), Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ g() ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΡΠΈΠ½Ρ…Ρ€ΠΎΠ½ΠΈΠ·Π°Ρ†ΠΈΡŽ посрСдством ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° syncObject. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Π΄Π²Π° Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° синхронизации нСзависимы. ДСмонстрируСтся этот Ρ„Π°ΠΊΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ main(), Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ создаСтся ΠΏΠΎΡ‚ΠΎΠΊ Thread с Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° f(). ΠŸΠΎΡ‚ΠΎΠΊ main() послС этого Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ Π΄(). Из Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π²ΠΈΠ΄Π½ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ±Π° ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΈ Π½ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ… Π½Π΅ блокируСтся сосСдом.

Π›ΠΎΠΊΠ°Π»ΡŒΠ½Π°Ρ ΠΏΠ°ΠΌΡΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠ°

Π’Ρ‚ΠΎΡ€ΠΎΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ прСдотвращСния ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΠΎΠ² доступа ΠΊ ΠΎΠ±Ρ‰ΠΈΠΌ рСсурсам основан Π½Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΈ ΠΈΡ… совмСстного использования. Π›ΠΎΠΊΠ°Π»ΡŒΠ½Π°Ρ ΠΏΠ°ΠΌΡΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠ° прСдставляСт собой ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ автоматичСского выдСлСния Ρ€Π°Π·Π½Ρ‹Ρ… областСй памяти для ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π²ΠΎ всСх ΠΏΠΎΡ‚ΠΎΠΊΠ°Ρ…, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΡ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Ссли ΠΏΡΡ‚ΡŒ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ с ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Ρ…, для Ρ… Π±ΡƒΠ΄Π΅Ρ‚ сгСнСрировано ΠΏΡΡ‚ΡŒ Ρ€Π°Π·Π½Ρ‹Ρ… областСй памяти. ЀактичСски ΠΏΠΎΡ‚ΠΎΠΊ связываСтся с Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ состояниСм.

Π—Π° Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ локальной памяти ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΈ ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Сю ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ класс java.lang.ThreadLocal:

//: concurrency/ThreadLocalVariableHolder.java

// АвтоматичСскоС Π²Ρ‹Π΄Π΅Π»Π΅Π½ΠΈΠ΅ собствСнной памяти ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΡƒ.

import java util.concurrent.*, import java util *,

class Accessor implements Runnable { private final int id. public Accessor(int idn) { id = idn; } public void run() {

while( IThread.currentThreadO islnterrupted()) { ThreadLocalVariableHolder incrementO; System out println(this). Thread.yieldO.

}

}

public String toStringO {

return "#" + id + " " +

ThreadLocalVari ableHolder.get().

public class ThreadLocalVariableHolder {

private static ThreadLocal<Integer> value = new ThreadLocal<Integer>() {

private Random rand = new Random(47). protected synchronized Integer initialValueO { return rand.nextlnt(lOOOO).

}

}:

public static void incrementO {

value.set(value.get() + 1).

}

public static int get О { return value getO. } public static void main(String[] args) throws Exception {

ExecutorService exec = Executors newCachedThreadPoolО. for(int i = 0. i < 5. i++)

exec.execute(new Accessor(i)). TimeUnit.SECONDS.sleep(3); // НСбольшая Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° exec shutdownNowO, // Π’Ρ‹Ρ…ΠΎΠ΄ ΠΈΠ· всСх ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Accessor

}

} /* Output #0 9259 #1- 556 #2. 6694 #3- 1862 #4: 962 #0: 9260 #1- 557 #2: 6695 #3: 1863 #4: 963

*///:-

ΠžΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ThreadLocal ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ хранятся Π² статичСских полях. Если Π²Ρ‹ создаСтС ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ ThreadLocal, для обращСния ΠΊ содСрТимому ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ get() ΠΈ set(). ΠœΠ΅Ρ‚ΠΎΠ΄ get() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ копию ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, ассоциированного с ΠΏΠΎΡ‚ΠΎΠΊΠΎΠΌ, a set() сохраняСт свой Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°, возвращая Ρ€Π°Π½Π΅Π΅ Ρ…Ρ€Π°Π½ΠΈΠ²ΡˆΠΈΠΉΡΡ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚. Π˜Ρ… использованиС продСмонстрировано Π² ΠΌΠ΅Ρ‚ΠΎΠ΄Π°Ρ… increment() ΠΈ get() класса ThreadLocalVariableHolder. ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ increment^) ΠΈ get() Π½Π΅ синхронизированы, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ThreadLocal Π½Π΅ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ отсутствия «ситуации Π³ΠΎΠ½ΠΊΠΈΒ».

ВзаимодСйствиС ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ

Π˜Ρ‚Π°ΠΊ, ΠΌΡ‹ выяснили, Ρ‡Ρ‚ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠΈ способны ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚ΠΎΠ²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ с Π΄Ρ€ΡƒΠ³ΠΎΠΌ, ΠΈ Ρ€Π°Π·ΠΎΠ±Ρ€Π°Π»ΠΈΡΡŒ с Ρ‚Π΅ΠΌ, ΠΊΠ°ΠΊ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠΎΠ½Ρ„Π»ΠΈΠΊΡ‚Ρ‹. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ шагом Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΡΡ‚Π°Ρ‚ΡŒ ΠΈΠ·ΡƒΡ‡Π΅Π½ΠΈΠ΅ возмоТностСй взаимодСйствия ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ. ΠšΠ»ΡŽΡ‡Π΅Π²Ρ‹ΠΌ ΠΌΠΎΠΌΠ΅Π½Ρ‚ΠΎΠΌ Π² этом процСссС являСтся ΠΏΠΎΠ΄Ρ‚Π²Π΅Ρ€ΠΆΠ΄Π΅Π½ΠΈΠ΅ связи, бСзопасно Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅ΠΌΠΎΠ΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ wait() ΠΈ notify() класса Object. Π’ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ Java SE5 Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΡƒΡŽΡ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Condition с ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ await() ΠΈ signal(). ΠœΡ‹ рассмотрим Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°ΡŽΡ‰ΠΈΠ΅ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ ΠΈ ΠΈΡ… Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ.

ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ wait() ΠΈ notifyAII()

ΠœΠ΅Ρ‚ΠΎΠ΄ wait() ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ измСнСния Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ условия, Π½Π΅ΠΏΠΎΠ΄ΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»ΡŒΠ½ΠΎΠ³ΠΎ для Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°. Π”ΠΎΠ²ΠΎΠ»ΡŒΠ½ΠΎ часто это условиС измСняСтся Π² Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ выполнСния Π΄Ρ€ΡƒΠ³ΠΎΠΉ Π·Π°Π΄Π°Ρ‡ΠΈ. АктивноС ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅, Ρ‚ΠΎ Π΅ΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° условия Π² Ρ†ΠΈΠΊΠ»Π΅, Π½Π΅ΠΆΠ΅Π»Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΠ·-Π·Π° нСэффСктивного расходования Π²Ρ‹Ρ‡ΠΈΡΠ»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… рСсурсов. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, ΠΌΠ΅Ρ‚ΠΎΠ΄ wait() обСспСчиваСт ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ синхронизации дСйствий ΠΌΠ΅ΠΆΠ΄Ρƒ Π·Π°Π΄Π°Ρ‡Π°ΠΌΠΈ.

Π’Π°ΠΆΠ½ΠΎ ΠΏΠΎΠ½ΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΌΠ΅Ρ‚ΠΎΠ΄ sleep() Π½Π΅ освобоТдаСт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ. Π‘ Π΄Ρ€ΡƒΠ³ΠΎΠΉ стороны, ΠΌΠ΅Ρ‚ΠΎΠ΄ wait() снимаСт Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ с ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°, Ρ‚Π΅ΠΌ самым позволяя ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ синхронизированныС ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π²ΠΎ врСмя выполнСния wait(). Π­Ρ‚ΠΎ ΠΎΡ‡Π΅Π½ΡŒ Π²Π°ΠΆΠ½ΠΎ, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΈΠΌΠ΅Π½Π½ΠΎ Β«Π΄Ρ€ΡƒΠ³ΠΈΠ΅Β» ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ приводят ΠΊ измСнСнию условия ΠΈ Π°ΠΊΡ‚ΠΈΠ²ΠΈΠ·Π°Ρ†ΠΈΠΈ приостановлСнной Π·Π°Π΄Π°Ρ‡ΠΈ.

БущСствуСт Π΄Π²Π΅ Ρ„ΠΎΡ€ΠΌΡ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° wait(). Π£ ΠΏΠ΅Ρ€Π²ΠΎΠΉ Ρ„ΠΎΡ€ΠΌΡ‹ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΈΠΌΠ΅Π΅Ρ‚ Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅ смысл, ΠΊΠ°ΠΊ ΠΈ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° sleep(): это ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΈΠ½Ρ‚Π΅Ρ€Π²Π°Π»Π° Π² миллисСкундах, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ приостанавливаСтся Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΏΠΎΡ‚ΠΎΠΊΠ°. Π Π°Π·Π½ΠΈΡ†Π° ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΌΠ΅Ρ‚ΠΎΠ΄Π°ΠΌΠΈ состоит Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ:

1. ΠŸΡ€ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° wait() Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ освобоТдаСтся.

2. Π’Ρ‹ΠΉΡ‚ΠΈ ΠΈΠ· состояния оТидания, установлСнного wait(), ΠΌΠΎΠΆΠ½ΠΎ двумя способами: с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ увСдомлСния notify() ΠΈΠ»ΠΈ notifyAU() Π»ΠΈΠ±ΠΎ ΠΏΠΎ истСчСнии срока оТидания.

Вторая, Π±ΠΎΠ»Π΅Π΅ распространСнная Ρ„ΠΎΡ€ΠΌΠ° вызываСтся Π±Π΅Π· Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ². Π­Ρ‚Π° вСрсия ΠΌΠ΅Ρ‚ΠΎΠ΄Π° wait() заставит ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΡ€ΠΎΡΡ‚Π°ΠΈΠ²Π°Ρ‚ΡŒ, ΠΏΠΎΠΊΠ° Π½Π΅ ΠΏΡ€ΠΈΠ΄Π΅Ρ‚ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ notify() ΠΈΠ»ΠΈ notifyAll().

ΠŸΠΎΠΆΠ°Π»ΡƒΠΉ, самоС интСрСсноС Π² ΠΌΠ΅Ρ‚ΠΎΠ΄Π°Ρ… wait(), notify() ΠΈ notifyAU() β€” ΠΈΡ… ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ½ΠΎΡΡ‚ΡŒ ΠΊ ΠΎΠ±Ρ‰Π΅ΠΌΡƒ классу Object, Π° Π½Π΅ ΠΊ классу ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² Thread. Π₯отя это ΠΈ каТСтся Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Π½Π΅Π»ΠΎΠ³ΠΈΡ‡Π½Ρ‹ΠΌ β€” Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ‡Π΅Π³ΠΎ-Ρ‚ΠΎ, относящСгося ΠΈΡΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΊ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡƒ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ², Π² ΠΎΠ±Ρ‰Π΅ΠΌ Π±Π°Π·ΠΎΠ²ΠΎΠΌ классС β€” Π½Π° самом Π΄Π΅Π»Π΅ это Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ ΠΎΠΏΡ€Π°Π²Π΄Π°Π½ΠΎ, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΎΠ·Π½Π°Ρ‡Π΅Π½Π½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΡƒΡŽΡ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°ΠΌΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠ²Π»ΡΡŽΡ‚ΡΡ Ρ‡Π°ΡΡ‚ΡŒΡŽ любого ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. Π’ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π΅ ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠ΅ (wait()) ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π² любом синхронизированном ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅, нСзависимо ΠΎΡ‚ Ρ‚ΠΎΠ³ΠΎ, наслСдуСт Π»ΠΈ класс ΠΎΡ‚ Thread ΠΈΠ»ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΠ΅Ρ‚ Runnable. Π’ΠΎΠΎΠ±Ρ‰Π΅ говоря, СдинствСнноС мСсто, Π³Π΄Π΅ допустимо Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ wait(), β€” это синхронизированный ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΈΠ»ΠΈ Π±Π»ΠΎΠΊ (ΠΌΠ΅Ρ‚ΠΎΠ΄ sleep() ΠΌΠΎΠΆΠ½ΠΎ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ Π² любом мСстС, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ Π½Π΅ ΠΌΠ°Π½ΠΈΠΏΡƒΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΎΠΉ). Если Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄ wait() ΠΈΠ»ΠΈ notify() Π² ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΌ ΠΌΠ΅Ρ‚ΠΎΠ΄Π΅, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° скомпилируСтся, ΠΎΠ΄Π½Π°ΠΊΠΎ ΠΏΡ€ΠΈ Π΅Π΅ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ IllegalMonitorStateException с нСсколько Ρ‚ΡƒΠΌΠ°Π½Π½Ρ‹ΠΌ сообщСниСм Β«Ρ‚Π΅ΠΊΡƒΡ‰ΠΈΠΉ ΠΏΠΎΡ‚ΠΎΠΊ Π½Π΅ являСтся Π²Π»Π°Π΄Π΅Π»ΡŒΡ†Π΅ΠΌΒ» (Β«current thread not ownerΒ»). Π­Ρ‚ΠΎ сообщСниС ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ ΠΏΠΎΡ‚ΠΎΠΊ, Π²ΠΎΡΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Π²ΡˆΠΈΠΉ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ wait(), notify() ΠΈΠ»ΠΈ notifyAll(), Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ «хозяином» Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠ΅ΠΌΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° (ΠΎΠ²Π»Π°Π΄Π΅Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ) ΠΏΠ΅Ρ€Π΅Π΄ Π²Ρ‹Π·ΠΎΠ²ΠΎΠΌ любого ΠΈΠ· Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ².

Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Β«ΠΏΠΎΠΏΡ€ΠΎΡΠΈΡ‚ΡŒΒ» ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ провСсти ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΅Π³ΠΎ собствСнного ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ. Для этого Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ сначала Π·Π°Ρ…Π²Π°Ρ‚ΠΈΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ для Π΄Π°Π½Π½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°. НапримСр, Ссли Π²Ρ‹ Ρ…ΠΎΡ‚ΠΈΡ‚Π΅ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ notifyAll() для ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Ρ…, Ρ‚ΠΎ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ это Π² синхронизируСмом Π±Π»ΠΎΠΊΠ΅, ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‰Π΅ΠΌ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ для Ρ…:

synchronized(x) { Ρ… notifyAllО;

}

Рассмотрим простой ΠΏΡ€ΠΈΠΌΠ΅Ρ€. Π’ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ WaxOMatic.java задСйствованы Π΄Π²Π° процСсса: ΠΎΠ΄ΠΈΠ½ наносит Π²ΠΎΡΠΊΠΎΠ²ΡƒΡŽ пасту Π½Π° Π°Π²Ρ‚ΠΎΠΌΠ°ΡˆΠΈΠ½Ρƒ (Π‘Π°Π³), Π° Π΄Ρ€ΡƒΠ³ΠΎΠΉ ΠΏΠΎΠ»ΠΈΡ€ΡƒΠ΅Ρ‚ Π΅Π΅. Π—Π°Π΄Π°Ρ‡Π° ΠΏΠΎΠ»ΠΈΡ€ΠΎΠ²ΠΊΠΈ Π½Π΅ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΡ€ΠΈΡΡ‚ΡƒΠΏΠΈΡ‚ΡŒ ΠΊ Ρ€Π°Π±ΠΎΡ‚Π΅ Π΄ΠΎ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ Π·Π°Π΄Π°Ρ‡Π° нанСсСния пасты Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ свою ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΡŽ, Π° Π·Π°Π΄Π°Ρ‡Π° нанСсСния пасты Π΄ΠΎΠ»ΠΆΠ½Π° ΠΆΠ΄Π°Ρ‚ΡŒ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ ΠΏΠΎΠ»ΠΈΡ€ΠΎΠ²ΠΊΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π°Π»ΠΎΠΆΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ слой пасты. Оба класса, WaxOn ΠΈ WaxOff, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ Π‘Π°Π³, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ приостанавливаСт ΠΈ возобновляСт Π·Π°Π΄Π°Ρ‡ΠΈ Π² ΠΎΠΆΠΈΠ΄Π°Π½ΠΈΠΈ измСнСния условия:

//: concurrency/waxomatic/WaxOMatic.java // ΠŸΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅Π΅ взаимодСйствиС Π·Π°Π΄Π°Ρ‡, package concurrency.waxomatic, import java.util concurrent.*; import static net.mindview util.Print.*;