Многопоточность с семафорамиJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Многопоточность с семафорами

Сообщение Anonymous »

По сути, это проблема, которую я пытаюсь решить:

Дэвид, Шон и Фрэнк постоянно сажают семена. Дэвид роет ямы. Затем Шон
кладет по семечку в каждую лунку. Затем Фрэнк заполняет дыру. Существует несколько
ограничений синхронизации:
  • Шон не может посадить семя, если не существует хотя бы одной пустой лунки, но Шон это делает
    не важно, насколько Дэвид опережает Шона.
  • Фрэнк не может заполнить дыру, если не существует хотя бы одной дыры, в которой Шон имеет успех
    посадил семя, но ямка еще не засыпана. Фрэнка не волнует, насколько
    далеко Шон опередит Фрэнка.
  • Фрэнка волнует, что Дэвид не забивает больше MAX лунок впереди
    Фрэнка. Таким образом, если незаполненных ям МАКСИМАЛЬНО, Дэвиду придется подождать.
  • Есть только одна лопата, которой Дэвиду и Фрэнку нужно копать. и заполните
    дыры соответственно.
Напишите псевдокод для трех процессов, которые представляют Дэвида и Шона и Фрэнк
использовал семафоры в качестве механизма синхронизации. Обязательно инициализируйте
семафоры.

И это мое решение, реализованное на Java, которое, я знаю, не очень элегантное и своего рода расточительно по сравнению со стандартным решением:

Код: Выделить всё

import java.util.concurrent.Semaphore;

public class Holes {
private static final int MAX = 3;
private static final Semaphore mutexForShovel = new Semaphore(1, true);
private static final Semaphore mutexForHoleCount = new Semaphore(1, true);
private static int emptyHoleCount = 0, seededHoleCount = 0, finishedHoleCount = 0;

public static void main(String[] args) {
new Thread(() -> { // David
try {
while (true) {
if (emptyHoleCount < MAX) {
mutexForShovel.acquire(); // wait for shovel
System.out.println("David is digging a hole...");
Thread.sleep(200); // try annotating this
mutexForShovel.release(); // release shovel
mutexForHoleCount.acquire(); // enter critical section
emptyHoleCount++;
mutexForHoleCount.release(); // exit critical section
System.out.println("Empty = " + emptyHoleCount +
" Seeded = " + seededHoleCount +
" Finished = " + finishedHoleCount);
}
}
} catch (InterruptedException e) {
System.out.println(e.toString());
}
}).start();

new Thread(() -> { // Sean
while (true) {
try {
if (emptyHoleCount > 0) {
System.out.println("Sean is seeding a hole...");
Thread.sleep(200); // try annotating this
mutexForHoleCount.acquire(); // enter critical section
emptyHoleCount--;
seededHoleCount++;
mutexForHoleCount.release(); // exit critical section
System.out.println("Empty = " + emptyHoleCount +
" Seeded = " + seededHoleCount +
" Finished = " + finishedHoleCount);
}
} catch (InterruptedException e) {
System.out.println(e.toString());
}
}
}).start();

new Thread(() -> { // Frank
while (true) {
try {
if (seededHoleCount > 0) {
mutexForShovel.acquire(); // ask for shovel
System.out.println("Frank is filling a hole...");
Thread.sleep(200); // try annotating this
mutexForShovel.release(); // release shovel
mutexForHoleCount.acquire(); // enter critical section
seededHoleCount--;
finishedHoleCount++;
mutexForHoleCount.release(); // exit critical section
System.out.println("Empty = " + emptyHoleCount +
" Seeded = " + seededHoleCount +
" Finished = " + finishedHoleCount);
}
} catch (InterruptedException e) {
System.out.println(e.toString());
}
}
}).start();
}
}
Мне казалось, что я расположил операции получения() и Release() таким образом, чтобы избежать каких-либо «удержаний и ожиданий» и, таким образом, избежать тупиковой ситуации. Однако вот результат, который я получил при запуске в терминале:

Код: Выделить всё

David is digging a hole...
Empty = 1 Seeded = 0 Finished = 0
David is digging a hole...
Empty = 2 Seeded = 0 Finished = 0
David is digging a hole...
Empty = 3 Seeded = 0 Finished = 0
Как бы я ни был в замешательстве, я прогнал его построчно в отладчике и вот что получил:

Код: Выделить всё

David is digging a hole...
Sean is seeding a hole...
Frank is filling a hole...
Empty = 1 Seeded = 0 Finished = 0
Empty = 0 Seeded = 1 Finished = 0
David is digging a hole...
Empty = 1 Seeded = 0 Finished = 1
Sean is seeding a hole...
David is digging a hole...
Empty = 0 Seeded = 0 Finished = 1
Empty = 0 Seeded = 1 Finished = 1
Frank is filling a hole...
Empty = 1 Seeded = 1 Finished = 1
Empty = 1 Seeded = 0 Finished = 2
Sean is seeding a hole...
David is digging a hole...
...
Это разумный результат! Не так ли? Двигаясь дальше, я удалил аннотированные строки Thread.sleep() и получил следующее:

Код: Выделить всё

...
Sean is seeding a hole...
Frank is filling a hole...
Empty = 2 Seeded = 0 Finished = 29748
Empty = 2 Seeded = 1 Finished = 29747
Sean is seeding a hole...
Frank is filling a hole...
Empty = 1 Seeded = 1 Finished = 29748
Empty = 1 Seeded = 0 Finished = 29749
Sean is seeding a hole...
Frank is filling a hole...
Empty = 0 Seeded = 1 Finished = 29749
Empty = 0 Seeded = 0 Finished = 29750

Process finished with exit code 130 (interrupted by signal 2: SIGINT)
Что опять же является достойным результатом!
Поэтому у меня теперь два вопроса:
Вопрос 1. Предполагает ли исходный вывод терминала, что произошла взаимоблокировка? Если да, то какая часть моего кода неверна и как я могу ее изменить?
Вопрос 2. Почему я получаю разные результаты при запуске один и тот же код по-разному?
Большое спасибо!!!

Подробнее здесь: https://stackoverflow.com/questions/655 ... semaphores
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Синхронизация процессов для разных процессов, не работающих с двумя семафорами [дубликат]
    Anonymous » » в форуме C++
    0 Ответы
    43 Просмотры
    Последнее сообщение Anonymous
  • Многопоточность Тессеракта в C#
    Гость » » в форуме C#
    0 Ответы
    20 Просмотры
    Последнее сообщение Гость
  • Означает ли асинхронное программирование многопоточность?
    Anonymous » » в форуме Jquery
    0 Ответы
    30 Просмотры
    Последнее сообщение Anonymous
  • Многопоточность Python Selenium, «отдельный экземпляр WebDriver»
    Anonymous » » в форуме Python
    0 Ответы
    21 Просмотры
    Последнее сообщение Anonymous
  • Многопоточность — C++ — эмуляция асинхронного поведения в Python
    Anonymous » » в форуме C++
    0 Ответы
    28 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»