CodeGym /Kursy Java /Moduł 3 /Synchronizery: Synchronizacja dostępu do zasobów w Javie

Synchronizery: Synchronizacja dostępu do zasobów w Javie

Moduł 3
Poziom 19 , Lekcja 4
Dostępny

Semafor

Semafory są zwykle używane, gdy konieczne jest ograniczenie liczby wątków podczas pracy z systemem plików. Dostęp do pliku lub innego udostępnionego zasobu jest kontrolowany przez licznik. Jeśli jego wartość jest większa od zera, dostęp jest dozwolony, ale jednocześnie licznik się zmniejszy.

W momencie, gdy licznik zwróci zero, bieżący wątek zostanie zablokowany do czasu zwolnienia zasobu przez inny wątek. Liczba parametrów uprawnień musi być ustawiona za pomocą konstruktora.

Musisz wybrać ten parametr indywidualnie, w zależności od mocy komputera lub laptopa.

public class Main {

   public static void main(String[] args) {
       Semaphore sem = new Semaphore(1);
       CommonResource res = new CommonResource();
       new Thread(new MyThread(res, sem, "MyThread_1")).start();
       new Thread(new MyThread(res, sem, "MyThread_2")).start();
       new Thread(new MyThread(res, sem, "MyThread_3")).start();
   }
}

class CommonResource {
   int value = 0;
}

class MyThread implements Runnable {
   CommonResource commonResource;
   Semaphore semaphore;
   String name;
   MyThread(CommonResource commonResource, Semaphore sem, String name) {
       this.commonResource = commonResource;
       this.semaphore = sem;
       this.name = name;
   }

   public void run() {

       try {
           System.out.println(name + "waiting permission");
           semaphore.acquire();
           commonResource.value = 1;
           for (int i = 1; i < 7; i++) {
               System.out.println(this.name + ": " + commonResource.value);
               commonResource.value++;
               Thread.sleep(150);
           }
       } catch (InterruptedException e) {
           System.out.println(e.getMessage() + " " + name);
           Thread.currentThread().interrupt();
       }
       System.out.println(name + "releases permission");
       semaphore.release();
   }
}

CountDownLatch i inne

CountDownLatch — umożliwia wielu wątkom oczekiwanie na zakończenie określonej liczby operacji wykonanych na innych wątkach. Przykładem jest instalacja aplikacji: nie rozpocznie się, dopóki nie zaakceptujesz warunków użytkowania, dopóki nie wybierzesz folderu, w którym ma zostać zainstalowany nowy program i tak dalej. Jest do tego specjalna metoda countDown() - ta metoda zmniejsza licznik odliczania o jeden.

Gdy tylko liczba spadnie do zera, wszystkie oczekujące wątki w oczekiwaniu będą kontynuować swoją pracę, a wszystkie kolejne wywołania oczekiwania przejdą bez czekania. Licznik odliczania jest licznikiem jednorazowym i nie można go zresetować.

CyclicBarrier - służy do synchronizacji określonej liczby wątków w jednym punkcie. Bariera zostaje osiągnięta, gdy N wątków wywołuje metodę await(...) i blokuje. Następnie licznik zostaje zresetowany do pierwotnej wartości, a oczekujące wątki zostaną zwolnione. Dodatkowo w razie potrzeby istnieje możliwość uruchomienia niestandardowego kodu przed odblokowaniem wątków i wyzerowaniem licznika. W tym celu obiekt z implementacją interfejsu Runnable jest przekazywany przez konstruktora .

Exchanger<V> klasa Exchanger jest przeznaczona do wymiany danych pomiędzy wątkami. Jest wpisany i określa typ danych, które wątki muszą wymieniać.

Dane są wymieniane przy użyciu jedynej metody exchange() tej klasy :

V exchange(V x) throws InterruptedException
V exchange(V x, long timeout, TimeUnit unit) throws InterruptedException, TimeoutException

Parametr x reprezentuje bufor danych do wymiany. Druga forma metody definiuje również parametr timeout , timeout i unit , typ jednostki czasu używanej dla parametru timeout .

Klasa Phaser umożliwia synchronizację wątków reprezentujących pojedynczą fazę lub etap w wykonywaniu ogólnej akcji. Phaser definiuje obiekt synchronizacji, który czeka na zakończenie określonej fazy. Następnie Phaser przechodzi do następnego etapu lub fazy i czeka na jej ponowne zakończenie.

Podczas pracy z klasą Phaser często najpierw tworzy się jej obiekt. Następnie musimy zarejestrować wszystkich uczestników. Aby zarejestrować każdego uczestnika, należy wywołać metodę register() lub można zrezygnować z tej metody, przekazując wymaganą liczbę uczestników do konstruktora Phaser .

Następnie każdy uczestnik wykonuje określony zestaw czynności składających się na fazę. A synchronizator Phaser czeka, aż wszyscy uczestnicy zakończą wykonywanie fazy. Aby poinformować synchronizator, że faza się zakończyła, uczestnik musi wywołać metodę arrival() lub arrivalAndAwaitAdvance() . Następnie synchronizator przechodzi do następnej fazy.

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION