Программирование на Java с использованием семафоров и общих переменных

#java #semaphore #parallel-processing

#java #семафор #параллельная обработка

Вопрос:

Всем привет, мне нужно выполнить задание в школе, и я действительно не знаю, с чего начать. Мне не нужно решение целиком, а скорее советы и то, как с этим начать. Извините, но я новичок в программировании. Вот задача:

Доска объявлений (40p) используется для размещения уведомлений об аренде квартир. Каждое уведомление об аренде включает в себя 3 отрывные вкладки с указанием номера телефона. Группа из n студентов просматривает доску в поисках квартир. Каждый студент случайным образом выбирает 3 разных раздела и пытается удалить по одной вкладке из каждого из 3 соответствующих уведомлений. Если учащемуся удается взять 3 вкладки, которые он / она выбрал, он / она уходит, в противном случае он / она не берет ни одной, делает паузу на произвольное количество времени, а затем пытается снова с новым выбором из 3 разных разделов. Моделирование заканчивается, когда все учащиеся уходят. Предположим, что на плате есть место для сводных отчетов (n / 3). Разработайте параллельную программу, которая имитирует действия студентов, используя только семафоры для синхронизации. Представлять студентов как параллельные процессы. Обязательно объявляйте и инициализируйте общие переменные, которые вы используете для взаимодействия с процессами и синхронизации. Постарайтесь максимально увеличить параллелизм. Кратко объясните, как работает ваше решение и как оно позволяет избежать взаимоблокировки.


обновите, чтобы включить информацию, предоставленную в качестве ответа

Вот мой код на данный момент! Я в правильном направлении!?

 private static Semaphore[] apartments;

public void setApartments()
{
    apartments = new Semaphore[3];
    for(int i = 0; i < 3; i  )
        apartments[i] = new Semaphore(3);
}

@Override
    public void run()
    {
        setApartments();
        Random random = new Random();

    while(counter < 3)
    {
        try
        {
            acquired = apartments[random.nextInt(3)].tryAcquire();
            if(acquired)
                System.out.println("Student"   id   " succeded.");
            else
                System.out.println("Student"   id   " failed.");

            counter  ;
        }
        catch(Exception e) {e.printStackTrace();}
    }
}
  

У меня есть одна проблема, которую я не могу решить.
У меня одновременно запущено 4 потока, которые передают по одному разрешению за раз от:
статический семафор tabsA = новый семафор(3);

Так что мой поток будет выполняться вечно, потому что он ничего не получит. Но если я использую tabsA.release(); когда поток не соответствует требованиям, все четыре потока могут получать разрешения, даже если в семафоре (3) есть 3 разрешения. Я мог бы даже запустить 10 потоков, и это сработало бы. Как получилось?

Комментарии:

1. Вам нужно использовать это: download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent /… , предположительно

2. Итак, учитывая лекции курса и справочную информацию по книгам, объясните некоторые мысли / идеи / алгоритмы о том, как можно подойти к решению . В этой схеме не обязательно должно быть ничего специфичного для Java — просто используйте концепции параллелизма, которым учат в классе (и «используйте только семафоры»).

Ответ №1:

Как правило, я не люблю отвечать на домашние вопросы напрямую, но вы, возможно, захотите сосредоточить свое исследование на Random классе с его nextInt(int) методом, List<T> интерфейсе и его реализациях, Runnable интерфейсе (и Thread классе) и Semaphore классе с его tryAcquire() и release() методами).

Комментарии:

1. Просто убедитесь, что вы не вызываете release() метод семафора, если вам не удалось сначала получить от него разрешение… (Я НИКОГДА раньше не совершал подобной ошибки или чего-то подобного! невинно свистит )

2. используйте try { получить разрешение}, наконец, { разрешение на выпуск } здесь 🙂

3. @ChrisDennett: Э, согласно спецификации для этого приложения, вы хотите выдавать разрешения только в том случае, если вы не смогли собрать все три случайно выбранных.

Ответ №2:

Я бы предложил писать это последовательно (т. Е. по одному студенту за раз), просто чтобы заставить ваши базовые объекты / методы / алгоритмы работать должным образом. Это должно быть относительно просто для вас. Затем вернитесь, когда начнете рефакторинг для обеспечения параллелизма, и задайте соответствующие вопросы.

Комментарии:

1. Итак, одно разрешение соответствует одному уведомлению?

Ответ №3:

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

Семафоры — это, по сути, способ объявить, что существует ограниченное количество ресурсов. Когда процесс пытается получить семафор, он в основном запрашивает разрешение на использование ресурса, который семафор символически охраняет. Когда процесс, получивший разрешение, завершает работу с ресурсом, он должен освободить разрешение, чтобы другой процесс мог его получить. Если процесс хочет ждать (потенциально вечно) получения разрешения на доступ в Java, он вызывает Semaphore.acquire() . Если процесс просто хочет попытаться получить разрешение, если оно немедленно доступно, или сделать что-то еще иным образом, в Java он вызывает Semaphore.tryAcquire() .