#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()
.