4. Семафоры

Семафоры позволяют регулировать количество работающих потоков одновременно.


    public Semaphore(int permits, boolean fair) {
        sync = fair ? new FairSync(permits) : new NonfairSync(permits);
    }

permits указывает количество потоков fair указываем true или false.

если true то они будут запускаться ровно в том же порядке в котором были добавлены в очередь

у семафора есть два основных метода ecquire - что то похожее на wait release - отпускаем в релиз наш поток, освобождаем место в семафоре для следующих потоков


    import java.util.concurrent.Semaphore;

//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class Main {
    public static void main(String[] args) {
        //TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text
        // to see how IntelliJ IDEA suggests fixing it.
        Semaphore semaphore = new Semaphore(2,true);
        for (int i = 0; i < 10; i++) {
            new MyThread(semaphore).start();
        }
    }
}


class MyThread extends Thread{
    final Semaphore semaphore;

    MyThread(Semaphore semaphore) {
        this.semaphore = semaphore;
    }

    @Override
    public void run() {
        super.run();
        try {
            this.semaphore.acquire();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(this.getName()+" started...");
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(this.getName()+ " finished...");
       this.semaphore.release();

    }
}


пример

https://gitlab.com/synergy9980417/razdel2/2_6


Семафоры в Java - это класс Semaphore, который представляет собой механизм синхронизации, позволяющий ограничить количество потоков, которые могут одновременно выполнять определенный ресурс или операцию.

Семафоры используются для решения проблем доступа к общим ресурсам в многопоточных приложениях. Они позволяют ограничить количество потоков, которые могут одновременно использовать ресурс, тем самым предотвращая перегрузку ресурса и обеспечивая его корректную работу.

Пример использования семафора:

import java.util.concurrent.Semaphore;

public class PrintQueue {
    private final Semaphore semaphore;

    public PrintQueue() {
        semaphore = new Semaphore(3); // разрешаем 3 потока одновременно
    }

    public void printJob() throws InterruptedException {
        semaphore.acquire(); // запрашиваем доступ к ресурсу
        try {
            System.out.println("Печатаем документ...");
            Thread.sleep(1000); // имитируем печать
        } finally {
            semaphore.release(); // освобождаем доступ к ресурсу
        }
    }
}

В этом примере, класс PrintQueue имеет поле semaphore типа Semaphore, которое разрешает 3 потокам одновременно выполнять операцию печати. Метод printJob() запрашивает доступ к ресурсу с помощью метода acquire(), выполняет операцию печати, а затем освобождает доступ к ресурсу с помощью метода release().

Благодаря использованию семафора, мы можем быть уверены, что не более 3 потоков будут одновременно печатать документы, тем самым предотвращая перегрузку ресурса.