gpt4 book ai didi

java - 另一个就餐哲学家并发问题

转载 作者:行者123 更新时间:2023-11-30 07:25:00 25 4
gpt4 key购买 nike

这是哲学家就餐问题的另一个实现,这是家庭作业问题,我将在这里展示我迄今为止尝试过的内容:

/**
* DPServer.java
* <p>
* This class implements the methods called by the philosophers
*/
package cc;

import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class DPServer {

private static Lock chopstick[] = new Lock[5]; // Create chopstick locks
private static Lock mutex = new ReentrantLock(true);

private static int MAX_EAT_TIME = 5000; // maximum eating time in milliseconds
private static int MAX_THINK_TIME = 5000; // maximum thinking time in milliseconds
private static Random r = new Random(0);


// default constructor for DPServer class
public DPServer() {
for (int i = 0; i < 5; i++) {
chopstick[i] = new ReentrantLock(true);
} // end for

} // end DPServer default constructor


// called by a philosopher when they wish to eat
public void takeChopsticks(int philosopherNumber) {
// acquire chopstick[philosopherNumber] and chopstick[(philosopherNumber + 1) mod 5]
System.out.println("Acquiring chopstick[" + philosopherNumber + "] and chopstick[" + ((philosopherNumber + 1) % 5) + "]");
chopstick[philosopherNumber].lock();
chopstick[(philosopherNumber + 1) % 5].lock();
// eat for a random number of milliseconds
int eatTime = r.nextInt(MAX_EAT_TIME);
System.out.println("Philosopher " + philosopherNumber + " is eating for " + eatTime + " milliseconds");
try {
Thread.sleep(eatTime);
} catch (InterruptedException ex) {
System.out.println("Philosopher " + philosopherNumber + " eatTime sleep was interrupted");
}

} // end takeChopsticks


// called by a philosopher when they are finished eating
public void returnChopsticks(int philosopherNumber) {
// release chopstick[philosopherNumber] and chopstick[(philosopherNumber + 1) mod 5]
System.out.println("Releasing chopstick[" + philosopherNumber + "] and chopstick[" + ((philosopherNumber + 1) % 5) + "]");
chopstick[(philosopherNumber + 1) % 5].unlock();
chopstick[philosopherNumber].unlock();

// think for a random number of milliseconds
int thinkTime = r.nextInt(MAX_THINK_TIME);
System.out.println("Philosopher " + philosopherNumber + " is thinking for " + thinkTime + " milliseconds");
try {
Thread.sleep(thinkTime);
} catch (InterruptedException ex) {
System.out.println("Philosopher " + philosopherNumber + " thinkTime sleep was interrupted");
}
}
}


// implementation of the Dining Philosopher class
package cc;

public class DPhilosopher {
private int dpNum;
private DPServer dpServ;

// value constructor for the DPhilosopher class
public DPhilosopher(int num, DPServer d) {
dpNum = num;
dpServ = d;
} // end DPhilosopher value constructor


public void DPEatThink() {
while (true) {
// get ready to eat
System.out.println("Philosopher " + dpNum + " is getting ready to eat");
dpServ.takeChopsticks(dpNum);

// finish eating
System.out.println("Philosopher " + dpNum + " is finished eating");
dpServ.returnChopsticks(dpNum);

}

}

public static void main(String[] args) {
DPServer dps = new DPServer();
DPhilosopher dp[] = new DPhilosopher[5];
Thread dpThread[] = new Thread[5];

// Create and launch the DPhilosopher threads
for (int i = 0; i < 5; i++) {
dp[i] = new DPhilosopher(i, dps);
final int finalI = i;
dpThread[i] = new Thread(new Runnable() {
@Override
public void run() {
dp[finalI].DPEatThink();
}
});
dpThread[i].start();
}

} // end main
}

除了 takeChopsticks() 之外,大部分代码都已准备就绪和returnChopsticks()方法需要改变,我所做的就是添加这个:

chopstick[(philosopherNumber + 1) % 5].lock();
chopstick[philosopherNumber].lock();

chopstick[(philosopherNumber + 1) % 5].unlock();
chopstick[philosopherNumber].unlock();

我知道这不是线程安全的,并且这个 link也保证了这一点。真正的神话是老师希望我们使用 DPServer#mutex 来解决这个问题。锁定,我可以锁定/解锁 takeChopsticks() 中的互斥体和returnChopsticks()围绕锁定和解锁2个锁(chopstick[philosopherNumber].lock(); 和chopstick[(philosopherNumber + 1) % 5].lock();),但这会造成死锁。

我只是不知道如何仅使用一个互斥锁 ReentrantLock 来解决这个问题。

谁能帮我解决这个问题吗?

提前致谢。

最佳答案

如果你在获取锁的过程中加了一把锁,就像这样:

// called by a philosopher when they wish to eat
public void takeChopsticks(int philosopherNumber) {
// acquire chopstick[philosopherNumber] and chopstick[(philosopherNumber + 1) mod 5]
System.out.println("Acquiring chopstick[" + philosopherNumber + "] and chopstick[" + ((philosopherNumber + 1) % 5) + "]");

lockLock.lock();
chopstick[philosopherNumber].lock();
chopstick[(philosopherNumber + 1) % 5].lock();
lockLock.unlock();

// eat for a random number of milliseconds
int eatTime = r.nextInt(MAX_EAT_TIME);
System.out.println("Philosopher " + philosopherNumber + " is eating for " + eatTime + " milliseconds");
try {
Thread.sleep(eatTime);
} catch (InterruptedException ex) {
System.out.println("Philosopher " + philosopherNumber + " eatTime sleep was interrupted");
}

} // end takeChopsticks

那么一次只能有一位哲学家正在拿起筷子,但其他一切都将继续按预期进行。

另一种选择是更改筷子的索引,以便奇数编号的哲学家总是从拿起左边的筷子开始,而偶数编号的哲学家总是从拿起右边的筷子开始。由于这是一项家庭作业,我将把如何做到这一点的细节作为练习(实际上并不难,if-else 语句使它变得非常简单)。

关于java - 另一个就餐哲学家并发问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36928904/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com