Форум программистов, компьютерный форум, киберфорум
Java SE (J2SE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/103: Рейтинг темы: голосов - 103, средняя оценка - 4.63
0 / 0 / 0
Регистрация: 02.04.2018
Сообщений: 2

Задача об обедающих философах

27.04.2018, 18:54. Показов 21698. Ответов 2

Студворк — интернет-сервис помощи студентам
Доброго времени суток! Поиском пользовался, но ответа для себя не нашёл, поэтому создаю тему.

Имеется задача об обедающих философах. Пять философов сидят вокруг круглого стола, перед каждым философом стоит тарелка спагетти. Вилки лежат на столе между каждой парой ближайших философов. Каждый философ может либо есть, либо размышлять. Философ может есть только тогда, когда держит две вилки — взятую справа и слева.

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

Запрещено: сделать так, чтобы философ проверил одну вилку, взял её, если она свободна, проверил вторую, и если она занята, то освободил первую, и отправился ждать.

Саму задачу я решить могу, проблемы вызывает конкретно специальное решение. Помогите, пожалуйста.

Имеющиийся код:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Main {
 
    private final int count = 5;
    
    private Main() {
    
        Fork[] forks = new Fork[count];
        
        for(int i = 0; i < count; i++) {
            forks[i] = new Fork(1);
        }
        
        for(int i = 0; i < count; i++) {
            new Thread(new Philosopher(i, forks[(i + 1) % count], forks[i])).start();
        }
        
    }
    
    public static void main(String[] args) {
        new Main();
    }
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import java.lang.Runnable;
import java.util.Random;
 
class Philosopher implements Runnable {
 
    private final float chanceToEat = 0.3f; 
    private final float chanceToThink = 0.3f; 
    
    private int number;
 
    private Fork leftFork;
    private Fork rightFork;
    
    private Random random;
    
    private STATES state;
    
    private enum STATES {
        THINKING,
        EATING;
    }
    
    public Philosopher(int number, Fork leftFork, Fork rightFork) {
        this.number = number;
        this.leftFork = leftFork;
        this.rightFork = rightFork;
        
        random = new Random(System.nanoTime());
        state = STATES.THINKING;
    }
    
    boolean isTimeToEat() {
        return random.nextFloat() < chanceToEat;
    }
    
    boolean isTimeToThink() {
        return random.nextFloat() < chanceToThink;
    }
    
    @Override
    public void run() {
        System.out.println("Philosopher № " + number + " is thinking.");
        while(true) {
            try {
                switch(state) {
                    case THINKING:  if(isTimeToEat()) {
                                        System.out.println("Philosopher № " + number + " wants to eat.");
                                        // TODO
                                        // Ожидание обоих вилок
                                        state = STATES.EATING;
                                    }
                                    break;
                                    
                    case EATING:    if(isTimeToThink()) {
                                        // TODO
                                        // Освобождение обоих вилок
                                        System.out.println("Philosopher № " + number + " is thinking.");
                                        state = STATES.THINKING;
                                    }
                }
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.concurrent.Semaphore;
 
class Fork extends Semaphore {
    
    private static final long serialVersionUID = -9092936681187449008L;
    
    public Fork(int permits) {
        super(permits);
    }
    
    public Fork(int permits, boolean fair) {
        super(permits, fair);
    }
}
Добавлено через 53 минуты
Предположительно я нашёл решение (реализовал блоки TODO):
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import java.lang.Runnable;
import java.util.Random;
 
class Philosopher implements Runnable {
 
    private final float chanceToEat = 0.3f; 
    private final float chanceToThink = 0.3f; 
    
    private int number;
 
    private Fork leftFork;
    private Fork rightFork;
    
    private Random random;
    
    private STATES state;
    
    private enum STATES {
        THINKING,
        EATING;
    }
    
    public Philosopher(int number, Fork leftFork, Fork rightFork) {
        this.number = number;
        this.leftFork = leftFork;
        this.rightFork = rightFork;
        
        random = new Random(System.nanoTime());
        state = STATES.THINKING;
    }
    
    boolean isTimeToEat() {
        return random.nextFloat() < chanceToEat;
    }
    
    boolean isTimeToThink() {
        return random.nextFloat() < chanceToThink;
    }
    
    @Override
    public void run() {
        System.out.println("Philosopher № " + number + " is thinking.");
        while(true) {
            try {
                switch(state) {
                    case THINKING:  if(isTimeToEat()) {
                                        boolean wait = true;
                                        int i = 0;
                                        while(wait) {
                                            synchronized(leftFork) {
                                                synchronized(rightFork) {
                                                    if(leftFork.availablePermits() > 0 && rightFork.availablePermits() > 0) {
                                                        leftFork.acquire();
                                                        rightFork.acquire();
                                                        wait = false;
                                                        System.out.println("Philosopher № " + number + " is eating.");
                                                        state = STATES.EATING;
                                                    }
                                                    else {
                                                        if(i++ == 0) {
                                                            System.out.println("Philosopher № " + number + " is waiting.");
                                                        }
                                                        if(i > 100) {
                                                            System.out.println("DEADLOCK\tDEADLOCK\tDEADLOCK\tDEADLOCK\tDEADLOCK\t");
                                                        }
                                                        Thread.sleep(500);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    break;
                                    
                    case EATING:    if(isTimeToThink()) {
                                        leftFork.release();
                                        rightFork.release();
                                        System.out.println("Philosopher № " + number + " is thinking.");
                                        state = STATES.THINKING;
                                    }
                }
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
27.04.2018, 18:54
Ответы с готовыми решениями:

Задача об обедающих философах
Тема заезженная,но все таки. Интересует решение задачи &quot;Обедающих философов&quot;. Мне надо сделать решение этой задачи на формах...

Многопоточность: задача об обедающих философах
Доброго времени суток! Нужно перевести код с С++ с использованием библиотеки &lt;thread&gt; и &lt;mutex&gt; на WinAPI. Программа...

Многопоточность, задача об обедающих философах (семафоры)
#include &quot;iostream&quot; #include &quot;string&quot; #include &quot;windows.h&quot; #include &quot;process.h&quot; #include &lt;conio.h&gt; using namespace std; ...

2
Эксперт функциональных языков программированияЭксперт Java
 Аватар для korvin_
4576 / 2775 / 491
Регистрация: 28.04.2012
Сообщений: 8,780
27.04.2018, 22:52
Цитата Сообщение от klunics Посмотреть сообщение
проблемы вызывает конкретно специальное решение. Помогите, пожалуйста.
Делаешь вилки ресурсом, распределяемым сервисом, т.е. философ отправляет сервису вилок запрос на две вилки, сервис проверяет, если обе свободны, отдаёт их философу, иначе отвечает ему, что вилки заняты и философ отправляется думать. Сервис обрабатывает только один запрос за раз, т.е. не может выполнять их конкурентно, чем обеспечит корректность состояния вилок в каждый момент времени.

Ну и соответственно, после еды философ возвращает обе взятые вилки.
0
0 / 0 / 0
Регистрация: 02.04.2018
Сообщений: 2
28.04.2018, 09:46  [ТС]
korvin_, спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.04.2018, 09:46
Помогаю со студенческими работами здесь

Задача об обедающих философах [C++|Linux|ARM Mitel5000]
Всем привет) Собственно несколько дней я ковыряюсь с проблемой и не знаю как её решить) Условия задачи: За круглым столом расставлены...

Ординарная Сеть Петри для задачи об "обедающих философах"
Помогите с сетью Петри. дуб в этом Задача об обедающих философах. Пять философов отдыхают в пансионате. Каждый из философов может...

Задача о философах
Даны 5 философов, сидящих в круг, и 5 вилок. Каждый из них может: думать, брать правую вилку, брать левую вилку, есть, класть правую,...

Задача о философах с использованием событий
Пытаюсь разобраться с этой задачей . Задача: за круглым столом сидят философы. Их жизненный цикл состоит из двух состояний: ест и думает....

задача про обедающих философов
Здравствуйте! Делаю программу про обедающих философов. http://alice.pnzgu.ru/~dvn/prolog/articls/9.htm Хочу сделать через картинки....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru