Домой Учебники по Java и J2EE Что такое Java Semaphore и Mutex — параллелизм Java MultiThread объяснен на...

Что такое Java Semaphore и Mutex — параллелизм Java MultiThread объяснен на примере

5406
0

Java Concurrency — очень широкая тема. Существуют сотни учебных пособий и примеров, доступных для использования. Некоторое время назад я написал несколько руководств по параллельному запуску нескольких потоков в Java и различных типах синхронизированных блоков .

В этом уроке мы рассмотрим:

  1. Объяснение Mutex
  2. Объяснение семафора
  3. Два примера с деталями

Давайте начнем

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: (объяснение ниже)

CrunchifySemaphoreMutexTutorial.java

Джава
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 crunchifyList знак равно новый 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:

CrunchifyJavaSemaphoreTutorial.java

Джава
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 ( )
Что такое Java Semaphore и Mutex — параллелизм Java MultiThread объяснен на примере

0.00 (0%) 0 votes

ЧИТАТЬ ТАКЖЕ:  Как читать и анализировать файл CSV (значения, разделенные запятыми) в ArrayList в Java, используя операцию разделения?

ОСТАВЬТЕ ОТВЕТ

Пожалуйста, введите ваш комментарий!
пожалуйста, введите ваше имя здесь