Co to jest monitor w Javie?

133

Do jakiego monitora odnosi się programowanie współbieżne w języku Java?

Kiedy czytam, że „każdy obiekt ma powiązany monitor”, co to oznacza?

Czy to specjalny obiekt?

xdevel2000
źródło
12
+1 To sprawiło, że przeczytałem, jak monitory są implementowane na poziomie JVM. Nauczyłem się czegoś nowego
naikus
@naikus Spodziewam się udostępnienia od Ciebie szczegółów :)
roottraveller

Odpowiedzi:

91

Monitor to mechanizm kontrolujący jednoczesny dostęp do obiektu.

Dzięki temu możesz:

Wątek 1:

public void a()
{
    synchronized(someObject) {
        // do something (1)
    }
}

Wątek 2:

public void b()
{
    synchronized(someObject) {
        // do something else (2)
    }
}

Zapobiega to jednoczesnemu dostępowi wątków 1 i 2 do monitorowanej (zsynchronizowanej) sekcji. Jeden uruchomi się, a monitor uniemożliwi drugiemu dostęp do regionu przed zakończeniem pierwszego.

To nie jest specjalny przedmiot. Jest to mechanizm synchronizacji umieszczony u nasady hierarchii klas: java.lang.Object.

Są też waiti notifymetody, które będą również używać monitora obiektu do komunikacji między różnymi wątkami.

Pablo Santa Cruz
źródło
1
czy możemy więc powiedzieć, że kiedy tworzymy metodę synchroniczną, definiujemy blokadę (monitor) metody tego obiektu?
xdevel2000
30
Erm, nie do końca. Każdy obiekt ma automatycznie powiązany z nim monitor (mutex), niezależnie od wszystkiego innego. Kiedy deklarujesz zsynchronizowaną metodę, deklarujesz, że środowisko uruchomieniowe musi uzyskać blokadę na monitorze obiektu przed rozpoczęciem wykonywania tej metody (i musi zwolnić blokadę, zanim sterowanie powróci do kodu wywołującego).
Andrzej Doyle
34
I @Pablo - nie ma czegoś takiego jak monitor metody; monitory istnieją tylko dla obiektów, które byłyby otaczającą instancją dla większości metod lub odpowiednim Classobiektem dla metod statycznych. Jeśli masz już zsynchronizowaną metodę method1 () i zadeklarujesz synchronizację method2 (), nie zostaną utworzone żadne nowe monitory i faktycznie wywołanie jednej z metod (na tym samym obiekcie) spowoduje próbę zablokowania tego samego monitora. To często przyciąga nowoprzybyłych.
Andrzej Doyle
1
@Andrzej: czyli z każdym obiektem powiązany jest JEDEN monitor. Wtedy mogę mieć wiele zsynchronizowanych metod. Po każdej z tych metod wywołanie wątku uzyskuje monitor, który wykonuje synchronizację.
xdevel2000
1
wystarczy to wyjaśnić ... obiekt, który jest używany do wywołania zsynchronizowanego bloku w wątku 1, może być ponownie użyty w innym wątku (wątek 2) do wywołania zwykłej metody (niezsynchronizowanej) w tym samym czasie?
28

Monitor to jednostka posiadająca zarówno blokadę, jak i zestaw oczekiwania . W Javie każdy Objectmoże służyć jako monitor.

Aby uzyskać szczegółowe wyjaśnienie, jak działają monitory w Javie, polecam przeczytanie sekcji Mechanika monitorów w Programowaniu współbieżnym w Javie (powyższy link wyświetla podgląd w książkach Google, a ta sekcja jest dostępna do czytania).

JRL
źródło
Jak powiedziałeś "Monitor jest bytem ...", czy oznacza to, że monitor jest wewnętrznym obiektem / stanem, który posiada / śledzi blokadę i zestaw oczekiwania? Jeśli nie, czy możesz rozwinąć tutaj Entity? Zasadniczo, kiedy dokument java mówi Wakes up all threads that are waiting on this object's monitor. o notifyall (), otrzymuję to, że obiekt utrzymuje (za pomocą wewnętrznej jednostki / obiektu) to, co wszystkie wątki czekają na blokadę, ten wewnętrzny obiekt / obiekt nazywa się monitorem?
user3198603
Najbardziej przydatna odpowiedź. Dzięki @JRL.
gravetii
Dla mnie jest napisane: „Brak podglądu dla tej strony”.
opncow
11
  1. Monitor to koncepcja / mechanizm, który nie ogranicza się do języka Java;
  2. „W programowaniu współbieżnym monitor to obiekt lub moduł przeznaczony do bezpiecznego używania w więcej niż jednym wątku”;
  3. Jak każdy czytelnik wie, każdy obiekt w Javie jest podklasą java.lang.Object. Ludzie java stworzyli java.lang.Object w taki sposób, że ma on cechy i cechy, które umożliwiają programistom Java używanie dowolnego obiektu jako monitora. Na przykład, każdy obiekt ma kolejkę oczekiwania, kolejkę ponownego wejścia oraz metody czekania i powiadamiania, co czyni go monitorem;
  4. przeczytaj o monitorach tutaj .
mgibson
źródło
4

Język Java i system wykonawczy obsługują synchronizację wątków za pomocą monitorów.
Monitor jest powiązany z określonym elementem danych (zmienną warunkową) i działa jako blokada tych danych. Gdy wątek przechowuje monitor dla niektórych elementów danych, inne wątki są zablokowane i nie mogą sprawdzać ani modyfikować danych.


źródło
2

Monitor jest konstrukcją synchronizacyjną, która umożliwia wątkom zarówno wzajemne wykluczanie, jak i możliwość oczekiwania (blokowania) na spełnienie się określonego warunku.

Monitory posiadają również mechanizm sygnalizowania innym wątkom, że ich stan został spełniony. Jest to byt, który posiada zarówno blokadę, jak i zestaw oczekujący. W Javie każdy obiekt może służyć jako monitor.

W wirtualnej maszynie Java każdy obiekt i klasa jest logicznie powiązany z monitorem. Aby zaimplementować możliwość wzajemnego wykluczania monitorów, blokada (czasami nazywana muteksem) jest powiązana z każdym obiektem i klasą. Nazywa się to semaforem w terminach systemów operacyjnych, mutex to semafor binarny.

Więcej informacji znajdziesz w linku

Swati Gour
źródło
1

W programowaniu współbieżnym musimy skupić się na dwóch rzeczach

  1. Wzajemne wykluczenie

Gdy proces / wątek wykonuje sekcję krytyczną, żadne inne procesy nie mogą wykonywać sekcji krytycznej. (Każdy proces ma segment kodu o nazwie „Sekcja krytyczna”, w której uzyskuje się dostęp do udostępnionych danych).

  1. Synchronizacja

Kiedy wątki próbują osiągnąć wspólny cel poprzez współpracę, te wątki wymagają współpracy między nimi. Muszą się zsynchronizować, gdy koncentrują się na wspólnym celu.

Monitory służą do wzajemnego wykluczania i synchronizacji.


Jak łatwo zrozumieć Monitor?

Widok wysokiego poziomu monitora

Nie myl tego obszaru krytycznego z sekcją krytyczną, ponieważ tutaj obszar krytyczny wspomniany jest na poziomie obiektu, a nie na poziomie wątku. Udostępniane dane są uważane za obszar krytyczny.

Każdy obiekt i jego klasa są powiązane z monitorem. Zmienne instancji obiektów, które muszą być chronione przed równoczesnym dostępem, obejmowały obszar krytyczny dla monitora, który jest powiązany z obiektem i zmienne instancji klas / zmienne statyczne klasy, które muszą być chronione przed równoczesnym dostępem, zawarte w obszarze krytycznym dla monitor, który jest powiązany z klasą.

  • Ten krytyczny obszar jest chroniony zamkiem, który zapewnia wzajemne wykluczenie.

  • Zestaw Wait jest również powiązany z monitorem używanym do zapewnienia koordynacji między wątkami.

  • Zestaw wpisów jest używany do przechowywania wątków, które są już żądane dla blokady, a blokada nie została jeszcze przez nie uzyskana.

W jaki sposób osiąga się wzajemne wykluczenie w Monitorze?


Każdy obiekt jest powiązany z monitorem, a ten monitor ma blokadę, w której każdy wątek może zablokować lub odblokować obiekt za pomocą tej blokady, gdy uzyskuje dostęp do współdzielonych zmiennych. Mówiąc wprost, oznacza to, że tylko jeden wątek naraz może blokować monitor. Wszelkie inne wątki próbujące zablokować tę blokadę są blokowane, dopóki nie uzyskają blokady. gdy nowy wątek próbuje uzyskać blokadę i jeśli już wątek posiada blokadę, to ten wątek będzie czekał na zestaw wpisu, aby uzyskać blokadę. kiedy nić, która została zdobyta, blokada zakończy swoją krytyczną sekcję, zwolni blokadę. Zatem następny wątek otrzyma blokadę, ale ten następny wątek jest pobierany z zestawu wpisów i zostanie określony przez JVM na podstawie pewnych kryteriów, takich jak FIFO.

Tutaj osiągnęliśmy wzajemne wykluczenie, ponieważ dajemy wyłączny dostęp do wątku obiektu i nie pozwalamy żadnym innym wątkom wejść do ich krytycznej sekcji.

Przykładowy kod java umożliwiający wzajemne wykluczenie przy użyciu monitora

  class Counter
      {
            private int count = 0;
            public void synchronized Increment() {
                int n = count;
                count = n+1;
            } //Here synchronized is used to indicate those things should be done sequentially.
      }


W jaki sposób koordynacja / synchronizacja jest osiągana przez Monitor?

Synchronizacja jest osiągana za pomocą zestawu oczekiwania, który jest powiązany z monitorem oraz mechanizmu „czekaj i powiadamiaj” lub „sygnalizuj i kontynuuj”. Synchronizacja jest ważna, gdy jeden wątek wymaga, aby niektóre dane były w określonym stanie, a inny wątek jest odpowiedzialny za wprowadzenie danych do tego stanu, np. Problem producenta / konsumenta

Gdy wątek wywołuje metodę wait () w odniesieniu do obiektu, wówczas wątek zostaje zawieszony i dodany do zestawu wait, aby poczekać, aż inny wątek wywoła notify () lub notifyAll () na tym samym obiekcie.

Metoda notify () służy do wybudzania wątków znajdujących się w zestawie oczekiwania monitora określonego obiektu. Istnieją dwa sposoby powiadamiania o oczekujących wątkach.

  • notify () -> Dla wszystkich wątków oczekujących na wait ustaw metodę notify () powiadamia każdego z nich, aby wybudził się arbitralnie. Wybór, który dokładnie wątek ma się obudzić, jest niedeterministyczny i zależy od maszyny JVM.
  • notifyAll () -> Ta metoda po prostu budzi wszystkie wątki, które oczekują na ustawiony czas oczekiwania. Przebudzone wątki nie będą mogły kontynuować, dopóki bieżący wątek nie zwolni blokady tego obiektu. Przebudzone wątki będą konkurować w zwykły sposób z innymi wątkami, które mogą aktywnie konkurować o synchronizację.

Przykładowy kod java do osiągnięcia synchronizacji przy użyciu monitora w problemie producenta

class Buffer {
            private char [] buffer;
            private int count = 0, in = 0, out = 0;

            Buffer(int size)
            {
                 buffer = new char[size];
            }
 
            public synchronized void Put(char c) {
                 while(count == buffer.length) 
                 {
                      try { wait(); }
                      catch (InterruptedException e) { } 
                      finally { } 
                 } 
                 System.out.println("Producing " + c + " ...");
                 buffer[in] = c; 
                 in = (in + 1) % buffer.length; 
                 count++; 
                 notify(); 
            }
    
            public synchronized char Get() {
                 while (count == 0) 
                 {
                      try { wait(); }
                      catch (InterruptedException e) { } 
                      finally { } 
                 } 
                 char c = buffer[out]; 
                 out = (out + 1) % buffer.length;
                 count--;
                 System.out.println("Consuming " + c + " ..."); 
                 notify(); 
                 return c;
            }
      }

Zobacz poniższe linki http://www.csc.villanova.edu/~mdamian/threads/javamonitors.html#:~:text=Java%20associates%20a%20monitor%20with,the%20monitor%20for%20that%20object https: //howtodoinjava.com/java/multi-threading/how-to-use-locks-in-java-java-util-concurrent-locks-lock-tutorial-and-example/

rcvaram
źródło