Sobes.tech
Middle+

Pracovali ste so semaformi vo svojej praxi?

sobes.tech AI

Odpoveď od AI

Áno, používal som semafory, najmä v súvislosti s prácou s viacvláknovým spracovaním v Android aplikáciách.

Semafory v Jave (java.util.concurrent.Semaphore) slúžia na obmedzenie počtu vlákien, ktoré môžu súčasne pristupovať k určitému zdroju. To je užitočné v scenároch, kde má zdroj obmedzenú "kapacitu", napríklad pool pripojení alebo obmedzený počet dostupných slotov.

Hlavné metódy, s ktorými som pracoval:

  • acquire(): Zablokuje aktuálne vlákno, kým nie je dostupné povolenie.
  • acquire(int permits): Zablokuje aktuálne vlákno, kým nie je dostupný požadovaný počet povolení.
  • release(): Vráti povolenie semaforu, čím zvýši počet dostupných povolení.
  • release(int permits): Vráti požadovaný počet povolení.
  • tryAcquire(): Pokúsi sa získať povolenie bez blokovania vlákna.
  • availablePermits(): Vráti aktuálny počet dostupných povolení.

Príklad použitia:

import java.util.concurrent.Semaphore;

public class ResourcePool {

    private static final int MAX_AVAILABLE = 5;
    private final Semaphore permits = new Semaphore(MAX_AVAILABLE, true); // Spravodlivý semafor

    public void useResource() throws InterruptedException {
        permits.acquire(); // Žiadosť o povolenie
        try {
            // Logika použitia zdroja (napríklad práca s poolom pripojení)
            System.out.println(Thread.currentThread().getName() + " používa zdroj.");
            Thread.sleep(1000); // Simulácia práce so zdrojom
        } finally {
            permits.release(); // Uvoľnenie povolenia
            System.out.println(Thread.currentThread().getName() + " ukončil používanie zdroja.");
        }
    }

    public static void main(String[] args) {
        ResourcePool pool = new ResourcePool();
        // Vytvorenie viacerých vlákien, ktoré sa pokúsia použiť zdroj
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                try {
                    pool.useResource();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

V tomto príklade je semafor permits inicializovaný s 5 povoleniami, čo znamená, že súčasne môže byť vo vnútri bloku try, ktorý používa zdroj, iba 5 vlákien. Metóda acquire() blokuje vlákna, ak sú všetky povolenia obsadené, kým iné vlákna nevolajú release().

Semafory sú užitočné na riadenie prístupu k obmedzeným poolom zdrojov, ale je potrebné dávať pozor na potenciálne problémy, ako sú deadlocky, ak nesprávne spravujeme získavanie a uvoľňovanie povolení. Použitie try s finally na volanie release() je dobrá prax, ktorá zabezpečuje uvoľnenie zdrojov aj v prípade výnimiek.