Содержание
Java Concurrency — очень широкая тема. Существуют сотни учебных пособий и примеров, доступных для использования. Некоторое время назад я написал несколько руководств по параллельному запуску нескольких потоков в Java и различных типах синхронизированных блоков .
В этом уроке мы рассмотрим:
- Объяснение Mutex
- Объяснение семафора
- Два примера с деталями
Давайте начнем
Let's keep this in mind при чтении ниже объяснения:
- Возьмите пример Покупателя и Клиента
- Shopper одалживает ноутбуки
- Клиент может прийти и использовать ноутбук — клиенту нужен ключ для использования ноутбука
- После использования — клиент может вернуть ноутбук покупателю
Что такое Mutex (всего 1 тема):
У покупателя есть ключ к ноутбуку. Один клиент может иметь ключ — одолжить ноутбук — в то время. Когда задача заканчивается, Покупатель дает (освобождает) ключ следующему клиенту в очереди.
Official Definition :
«Mutex обычно используется для сериализации доступа к разделу re-entrant code тот cannot be executed concurrently более чем на один поток. Объект мьютекса позволяет только одному потоку в управляемый раздел, заставляя другие потоки, которые пытаются получить доступ к этому разделу, ждать, пока первый поток не выйдет из этого раздела ».
Другими словами: Mutex = Mutually Exclusive Semaphore
Что такое семафор (N указанных тем):
Скажем, теперь у Shopper 3 идентичных ноутбука и 3 идентичных ключа. Семафор это число free identical Laptop keys , Счетчик семафоров — количество ключей — вначале устанавливается на 3 (все три ноутбука свободны), затем значение счетчика уменьшается по мере поступления клиента. Если используются все ноутбуки, то есть не осталось свободных ключей для В ноутбуке число семафоров равно 0. Теперь, когда любой из клиентов возвращает ноутбук, семафор увеличивается до 1 (один свободный ключ) и передается следующему клиенту в очереди.
Official Definition : «Семафор ограничивает количество одновременных пользователей общего ресурса до максимального количества. Потоки могут запрашивать доступ к ресурсу (уменьшая семафор), и могут сигнализировать, что они закончили использовать ресурс (увеличивая семафор) ».
Другой должен прочитать: Ленивое создание экземпляра Singleton ThreadSafe
Пример-1: (объяснение ниже)
|
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
|
пакет crunchify. ком . учебник ;
Импортировать Java. Util. LinkedList ;
Импортировать Java. Util. одновременно. Семафор ;
/ **
* @author Crunchify.com
*
* /
общественности учебный класс CrunchifySemaphoreMutexTutorial {
статический объект crunchifyLock знак равно новый Объект ( ) ;
статический LinkedList
// Семафор поддерживает набор разрешений.
// Каждый получает блоки при необходимости, пока разрешение не доступно, а затем получает его.
// Каждый выпуск добавляет разрешение, потенциально освобождая блокирующий эквайер.
статический Семафор Семафор знак равно новый Семафор ( 0 ) ;
статический Семафор мьютекс знак равно новый Семафор ( 1 ) ;
// Я буду каждый раз создавать новое целое число
статический учебный класс CrunchifyProducer продолжается Нить {
общественности недействительным запустить ( ) {
ИНТ счетчик знак равно 1 ;
пытаться {
в то время как ( правда ) {
строка threadName знак равно Thread. currentThread ( ) . getName ( ) + counter ++ ;
мьютекс. приобретать ( ) ;
crunchifyList . добавить ( threadName ) ;
Система. вне. println ( Производитель устанавливает новое значение: + threadName ) ;
мьютекс. выпуск ( ) ;
// снять блокировку
семафор. выпуск ( ) ;
Thread. сон ( 500 ) ;
}
} ловить ( Исключение х ) {
х . printStackTrace ( ) ;
}
}
}
// Я буду употреблять Integer каждый раз
статический учебный класс CrunchifyConsumer продолжается Нить {
строка consumerName ;
общественности CrunchifyConsumer ( String имя ) {
это. consumerName знак равно имя ;
}
общественности недействительным запустить ( ) {
пытаться {
в то время как ( правда ) {
// получить блокировку Получает указанное количество разрешений от этого семафора, блокируя, пока все
// имеется в наличии
// процесс останавливается здесь, пока производитель не снимет блокировку
семафор. приобретать ( ) ;
// Получает разрешение от этого семафора, блокируя, пока один не доступен
мьютекс. приобретать ( ) ;
строка результат знак равно ;
за ( Строка значение : crunchifyList ) {
результат знак равно значение + , ;
}
Система. вне. println ( consumerName + потребляет значение: + результат + crunchifyList.size ():
+ crunchifyList . размер ( ) + / n ) ;
мьютекс. выпуск ( ) ;
}
} ловить ( Исключение е ) {
эл . printStackTrace ( ) ;
}
}
}
общественности статический недействительным main ( Строка [ ] аргументы ) {
новый CrunchifyProducer ( ) . начало ( ) ;
новый CrunchifyConsumer ( Хрустить ) . начало ( ) ;
новый CrunchifyConsumer ( Google ) . начало ( ) ;
новый CrunchifyConsumer ( Yahoo ) . начало ( ) ;
}
}
|
В вышеприведенном уроке CrunchifySemaphoreMutexTutorial.java когда CrunchifyProducer добавляет threadName в crunchifyList объект связанный список может сигнализировать семафор.
CrunchifyConsumer может попытаться получить семафор, поэтому они будут ждать, пока CrunchifyProducer не сообщит, что был добавлен идентификатор потока. При сигнале о добавленных данных один из потребителей будет разбужен, и он будет знать, что он может прочитать объект crunchifyList . Он может прочитать список, а затем вернуться к попытке получения на семафор.
Если за это время производитель написал другой пакет, он снова дал сигнал, и любой из потребителей затем продолжит читать другой пакет и так далее…
Другими словами:
|
1
2
3
|
CrunchifyProducer : Добавить объект о Список — Семафор. выпуск ( 1 )
CrunchifyConsumer Икс N ) — Семафор. приобрести ( 1 ) — Читайте объект из списка
|
Результат:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
Производитель является prdoucing новый значение : Нить — 01
Crunchify потребляет стоимость : Тема — 01 , crunchifyList . размер ( ) : 1
Производитель является prdoucing новый значение : Нить — 02
Google потребляет стоимость : Тема — 02 , crunchifyList . размер ( ) : 2
Производитель является prdoucing новый значение : Нить — 03
Yahoo потребляет стоимость : Тема — 03 , crunchifyList . размер ( ) : 3
Производитель является prdoucing новый значение : Нить — 04
Crunchify потребляет стоимость : Тема — 04 , crunchifyList . размер ( ) : 4
, , , , ,
, , , , ,
, , , , ,
|
Как предотвратить состояние гонки :
What if you have multiple Consumers? В приведенном выше руководстве по Java Потребители (не производитель) должны блокировать буфер при чтении пакета (но не при получении семафора), чтобы предотвратить состояние гонки. В приведенном ниже примере производитель также блокирует список, поскольку все находится на одной и той же JVM .
Пример-2:
|
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
|
пакет crunchify. ком . учебник ;
Импортировать Java. Util. одновременно. Семафор ;
/ **
* @author Crunchify.com
*
* /
общественности учебный класс CrunchifyJavaSemaphoreTutorial {
частный статический окончательный ИНТ MAX_CONCURRENT_THREADS знак равно 2 ;
частный окончательный Семафор crunchifyAdminLOCK знак равно новый Семафор ( MAX_CONCURRENT_THREADS , правда ) ;
общественности недействительным crunchifyStartTest ( ) {
за ( int я знак равно 0 ; я < 10 ; я ++ ) {
CrunchifyPerson person знак равно новый CrunchifyPerson ( ) ;
человек. начало ( ) ;
}
}
общественности учебный класс CrunchifyPerson продолжается Нить {
@Override
общественности недействительным запустить ( ) {
пытаться {
// Получить блокировку
crunchifyAdminLOCK . приобретать ( ) ;
} ловить ( InterruptedException е ) {
Система. вне. println ( «получено InterruptedException» ) ;
возврат ;
}
Система. вне. println ( Тема + это. getId ( ) + начать использовать машину Crunchify — Acquire () ) ;
пытаться {
сон ( 1000 ) ;
} ловить ( Исключение е ) {
} в конце концов {
// снять блокировку
crunchifyAdminLOCK . выпуск ( ) ;
}
Система. вне. println ( Тема + это. getId ( ) + перестает использовать машину Crunchify — Release () / n ) ;
}
}
общественности статический недействительным main ( Строка [ ] аргументы ) {
CrunchifyJavaSemaphoreTutorial test знак равно новый CrunchifyJavaSemaphoreTutorial ( ) ;
тест. crunchifyStartTest ( ) ;
}
}
|
Результат:
|
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
|
Нить 11 начать использовать машину Crunchify — Acquire ()
Тема 10 запуска с помощью Crunchify»s автомобиль — Получить ( )
Нить 10 перестает использовать машину Crunchify — Release ()
Тема 12 запуска с помощью Crunchify»s автомобиль — Получить ( )
Нить 13 начать использовать машину Crunchify — Acquire ()
Темы 11 остановок с использованием Crunchify»s автомобиль — Release ( )
Нить 13 перестает использовать машину Crunchify — Release ()
Тема 15 запуска с помощью Crunchify»s автомобиль — Получить ( )
Нить 14 начать использовать машину Crunchify — Acquire ()
Темы 12 остановок с использованием Crunchify»s автомобиль — Release ( )
Нить 14 перестает использовать машину Crunchify — Release ()
Тема 16 запуска с помощью Crunchify»s автомобиль — Получить ( )
Нить 15 перестает использовать машину Crunchify — Release ()
Тема 17 запуска с помощью Crunchify»s автомобиль — Получить ( )
Нить 17 перестает использовать машину Crunchify — Release ()
Тема 18 запуска с помощью Crunchify»s автомобиль — Получить ( )
Нить 19 начать использовать машину Crunchify — Acquire ()
Темы 16 остановок с использованием Crunchify»s автомобиль — Release ( )
Нить 18 перестает использовать машину Crunchify — Release ()
Темы 19 остановок с использованием Crunchify»s автомобиль — Release ( )
|
0.00 (0%) 0 votes






