浙江邮电工程建设有限公司网站,商城网站设计注意什么,centos wordpress建站,月子中心网站建设需求题目
有N个哲学家围坐在一张圆桌旁#xff0c;桌上只有N把叉子#xff0c;每对哲学家中间各有一把。
哲学家的两种行为#xff1a;
一、思考
二、吃意大利面
哲学家只能拿起手边左边或右边的叉子
吃饭需要两把叉子
正确地模仿哲学家的行为
方法一
一次只允许四个人…题目
有N个哲学家围坐在一张圆桌旁桌上只有N把叉子每对哲学家中间各有一把。
哲学家的两种行为
一、思考
二、吃意大利面
哲学家只能拿起手边左边或右边的叉子
吃饭需要两把叉子
正确地模仿哲学家的行为
方法一
一次只允许四个人抢叉子
import java.util.concurrent.Semaphore;
class 方法一 {public static class PhilosopherTest {//一次只允许四个人抢叉子static final Semaphore count new Semaphore(4);//五只叉子static final Semaphore[] mutex {new Semaphore(1),new Semaphore(1),new Semaphore(1),new Semaphore(1),new Semaphore(1)};static class Philosopher extends Thread {Philosopher(int name) {super.setName(String.valueOf(name));}Overridepublic void run() {do {try {//只有四个人有抢叉子的资格count.acquire();Integer i Integer.parseInt(super.getName());//规定都先拿左手边的叉子于是四个人左手都有叉子mutex[i].acquire();//大家开始抢右边的叉子mutex[(i 1) % 5].acquire();//谁先抢到谁第一个开吃System.out.println(哲学家 i 号吃饭);//吃完放下左手的叉子对于左边人来说就是他的右叉子直接开吃mutex[i].release();//再放下右手的叉子mutex[(i 1) % 5].release();//吃完了开始思考由于放下了右手的叉子相当于给一个叉子没有的哲学家一个左叉子count.release();//模拟延迟Thread.sleep(2000);} catch (InterruptedException e) {System.out.println(异常);}} while (true);}}public static void main(String[] args) {Philosopher[] threadsnew Philosopher[5];for (int i 0; i 5; i) {threads[i] new Philosopher(i);}for (Philosopher i : threads) {i.start();}}}
}count每次acquire就会减一使得第五个来访问的哲学家被阻塞
下面是将think和eat方法分离出来的改进版本
import java.util.concurrent.Semaphore;
public class 方法一改进 {public static class PhilosopherTest {// 一次只允许四个人抢叉子static final Semaphore count new Semaphore(4);// 五只叉子static final Semaphore[] mutex {new Semaphore(1),new Semaphore(1),new Semaphore(1),new Semaphore(1),new Semaphore(1)};static class Philosopher extends Thread {Philosopher(int name) {super.setName(String.valueOf(name));}Overridepublic void run() {do {try {think();eat();} catch (InterruptedException e) {System.out.println(异常);}} while (true);}public void think() throws InterruptedException {// 模拟思考System.out.println(哲学家 super.getName() 号正在思考);Thread.sleep(2000); // 模拟延迟}public void eat() throws InterruptedException {// 只有四个人有抢叉子的资格count.acquire();Integer i Integer.parseInt(super.getName());// 规定都先拿左手边的叉子于是四个人左手都有叉子mutex[i].acquire();// 大家开始抢右边的叉子mutex[(i 1) % 5].acquire();// 谁先抢到谁第一个开吃System.out.println(哲学家 i 号吃饭);// 吃完放下左手的叉子对于左边人来说就是他的右叉子直接开吃mutex[i].release();// 再放下右手的叉子mutex[(i 1) % 5].release();// 吃完了开始思考由于放下了右手的叉子相当于给一个叉子没有的哲学家一个左叉子count.release();}}public static void main(String[] args) {PhilosopherTest.Philosopher[] threadsnew PhilosopherTest.Philosopher[5];for (int i 0; i 5; i) {threads[i] new PhilosopherTest.Philosopher(i);}for (PhilosopherTest.Philosopher i : threads) {i.start();}}}}本质没区别。
方法二
先获取左筷子一段时间内申请不到右筷子就将左筷子释放
import java.util.concurrent.Semaphore;public class 方法二 {//先获取左筷子一段时间内申请不到右筷子就将左筷子释放// Five forksstatic final Semaphore[] mutex {new Semaphore(1),new Semaphore(1),new Semaphore(1),new Semaphore(1),new Semaphore(1)};static class Philosopher extends Thread {Philosopher(int name) {super.setName(String.valueOf(name));}Overridepublic void run() {do {try {Integer i Integer.parseInt(super.getName());//尝试获取左筷子if (mutex[i].tryAcquire()) {//尝试获取右筷子if (mutex[(i 1) % 5].tryAcquire()) {System.out.println(哲学家 i 号吃饭!);mutex[i].release();mutex[(i 1) % 5].release();Thread.sleep(2000);} else {//如果获取不到右筷子就把左筷子扔了mutex[i].release();}}//这里没有else获取不到左筷子就一直尝试} catch (InterruptedException e) {System.out.println(异常);}} while (true);}}public static void main(String[] args) {Philosopher[] threadsnew Philosopher[5];for (int i 0; i 5; i) {threads[i] new Philosopher(i);}for (Philosopher i : threads) {i.start();}}
}下面是将eat和think分出来的版本
import java.util.concurrent.Semaphore;
class 方法二改进 {//先获取左筷子一段时间内申请不到右筷子就将左筷子释放public static class Philosopher extends Thread {private static Semaphore[] chopsticks {new Semaphore(1), new Semaphore(1), new Semaphore(1), new Semaphore(1), new Semaphore(1)};private int id;public Philosopher(int id) {this.id id;}Overridepublic void run() {while (true) {think();eat();}}public void think() {System.out.println(哲学家_ this.id 正在思考);//思考一秒时间try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}public void eat() {try {if (chopsticks[this.id].tryAcquire()) { // 获取左筷子if (chopsticks[(this.id 1) % chopsticks.length].tryAcquire()) { // 获取右筷子System.out.println(哲学家_ this.id 正在吃饭);// 吃饭花一秒时间try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();} finally {chopsticks[this.id].release(); // 放下左筷子chopsticks[(this.id 1) % chopsticks.length].release(); // 放下右筷子}} else {chopsticks[this.id].release(); // 如果不能获取右筷子释放左筷子}}} catch (Exception e) {e.printStackTrace();}}public static void main(String[] args) {Philosopher[] threadsnew Philosopher[5];for (int i 0; i 5; i) {threads[i] new Philosopher(i);}for (Philosopher i : threads) {i.start();}}}}下面是用可重入锁实现的版本
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;class Philosopher extends Thread {private Lock leftFork;private Lock rightFork;private int philosopherId;private int eatCount; // 计数器public Philosopher(int philosopherId, Lock leftFork, Lock rightFork) {this.philosopherId philosopherId;this.leftFork leftFork;this.rightFork rightFork;this.eatCount 0;}private void think() throws InterruptedException {System.out.println(Philosopher philosopherId is thinking.);Thread.sleep((long) (Math.random() * 1000));}private void eat() throws InterruptedException {System.out.println(Philosopher philosopherId is eating.);Thread.sleep((long) (Math.random() * 1000));eatCount;}Overridepublic void run() {try {while (eatCount 1) { // 表示每个哲学家吃了1次think();/* 使用ReentrantLock锁, 该类中有一个tryLock()方法, 在指定时间内获取不到锁对象, 就从阻塞队列移除,不用一直等待。当获取了左手边的筷子之后, 尝试获取右手边的筷子, 如果该筷子被其他哲学家占用, 获取失败, 此时就先把自己左手边的筷子,给释放掉. 这样就避免了死锁问题 */if (leftFork.tryLock()) {System.out.println(Philosopher philosopherId picked up left fork.);if (rightFork.tryLock()) {System.out.println(Philosopher philosopherId picked up right fork.);eat();rightFork.unlock();System.out.println(Philosopher philosopherId put down right fork.);}leftFork.unlock();System.out.println(Philosopher philosopherId put down left fork.);}}} catch (InterruptedException e) {e.printStackTrace();}}
}class DiningPhilosophers {public static void main(String[] args) {int numPhilosophers 5;Philosopher[] philosophers new Philosopher[numPhilosophers];Lock[] forks new ReentrantLock[numPhilosophers];for (int i 0; i numPhilosophers; i) {forks[i] new ReentrantLock();}for (int i 0; i numPhilosophers; i) {philosophers[i] new Philosopher(i, forks[i], forks[(i 1) % numPhilosophers]);philosophers[i].start();}// 等待所有哲学家线程结束for (Philosopher philosopher : philosophers) {try {philosopher.join();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(All philosophers have finished eating. Program ends.);}
} 使用ReentrantLock锁, 该类中有一个tryLock()方法, 在指定时间内获取不到锁对象, 就从阻塞队列移除,不用一直等待。当获取了左手边的筷子之后, 尝试获取右手边的筷子, 如果该筷子被其他哲学家占用, 获取失败, 此时就先把自己左手边的筷子给释放掉. 这样就避免了死锁问题 方法三
奇数哲学家先左后右偶数科学家先右后左
import java.util.concurrent.Semaphore;public class 方法四 {//奇数哲学家先左后右偶数科学家先右后左// Five forksstatic final Semaphore[] mutex { new Semaphore(1),new Semaphore(1),new Semaphore(1),new Semaphore(1),new Semaphore(1) };static class Philosopher extends Thread {Philosopher(int name) {super.setName(String.valueOf(name));}Overridepublic void run() {do {try {Integer i Integer.parseInt(super.getName());if (i % 2 1) {// Odd-numbered philosopher// Try to acquire the left forkmutex[i].acquire();System.out.println(哲学家 i 号拿起左筷子);// Try to acquire the right forkmutex[(i 1) % 5].acquire();System.out.println(哲学家 i 号拿起右筷子);} else {// Even-numbered philosopher// Try to acquire the right forkmutex[(i 1) % 5].acquire();System.out.println(哲学家 i 号拿起右筷子);// Try to acquire the left forkmutex[i].acquire();System.out.println(哲学家 i 号拿起左筷子);}// EatSystem.out.println(哲学家 i 号吃饭!);// Release the forksmutex[i].release();mutex[(i 1) % 5].release();// Think (sleep for simulation)Thread.sleep(2000);} catch (InterruptedException e) {System.out.println(异常);}} while (true);}}public static void main(String[] args) {Philosopher[] threads new Philosopher[5];for (int i 0; i 5; i) {threads[i] new Philosopher(i);}for (Philosopher i : threads) {i.start();}}
}下面是将think和eat分开的版本
import java.util.concurrent.Semaphore;
public class 方法四改进 {public static class 方法四 {//奇数哲学家先左后右偶数科学家先右后左// Five forksstatic final Semaphore[] mutex { new Semaphore(1),new Semaphore(1),new Semaphore(1),new Semaphore(1),new Semaphore(1) };static class Philosopher extends Thread {Philosopher(int name) {super.setName(String.valueOf(name));}Overridepublic void run() {do {try {think();eat();} catch (InterruptedException e) {System.out.println(异常);}} while (true);}public void think() throws InterruptedException {Integer i Integer.parseInt(super.getName());System.out.println(哲学家 i 号正在思考);// Think (sleep for simulation)Thread.sleep(2000);}public void eat() throws InterruptedException {Integer i Integer.parseInt(super.getName());if (i % 2 1) {// Odd-numbered philosopher// Try to acquire the left forkmutex[i].acquire();System.out.println(哲学家 i 号拿起左筷子);// Try to acquire the right forkmutex[(i 1) % 5].acquire();System.out.println(哲学家 i 号拿起右筷子);} else {// Even-numbered philosopher// Try to acquire the right forkmutex[(i 1) % 5].acquire();System.out.println(哲学家 i 号拿起右筷子);// Try to acquire the left forkmutex[i].acquire();System.out.println(哲学家 i 号拿起左筷子);}// EatSystem.out.println(哲学家 i 号吃饭!);// Release the forksmutex[i].release();mutex[(i 1) % 5].release();}}public static void main(String[] args) {Philosopher[] threads new Philosopher[5];for (int i 0; i 5; i) {threads[i] new Philosopher(i);}for (Philosopher i : threads) {i.start();}}}}