黑马程序员--谈谈哲学家就餐的问题
2015-12-18 14:12
417 查看
----------- android培训、java培训、java学习型技术博客、期待与您交流! ---------
以前上课的时候听老师讲过哲学家就餐的问题,当时觉得似懂非懂的,因为对于多线程还不是很了解,现在归纳如下:
哲学家就餐问题是这样的:一圈哲学家就餐,一人左手拿着一支筷子,然后如果他右手边的哲学家给他筷子,他就能就餐,要不就饿死了,这是一个典型的多线程,而且带有死锁的问题。
图示是这样的:
![](https://img-blog.csdn.net/20151218141914338?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
代码示意:
package itheima;
class Test {
public boolean isLocked; //这是线程同步的
public Test() {
isLocked = false;
}
// 同步方法,当筷子必须false才能就餐
public synchronized void lock() throws InterruptedException {
while (isLocked)
wait();
isLocked = true; //锁上可防止同一支筷子被调用
}
public synchronized void unlock() { //解锁
isLocked = false;
notify(); //唤醒别的哲学家
}
}
class wood { //wood表示筷子
public char id; //每支筷子有自己的id
private Test lock = new Test(); //lock用于同步
public void get() throws InterruptedException {
lock.lock(); //筷子调用后加锁
}
public void put() throws InterruptedException {
lock.unlock(); //筷子释放后解锁
}
public wood(int j) { //构造函数
Integer i = new Integer(j);
id = i.toString().charAt(0);
}
}
//People代表哲学家
class People extends Thread {
public char move = '1';
//move代表哲学家的状态
private wood Left, Right; //分别表示左右筷子
// 构造函数,传进当前哲学家用的左右筷子编号
public People(wood left, wood right) {
super();
Left = left;
Right = right;
}
// run函数开始一个线程,代表当前哲学家的活动
public void run() {
int i;
try {
for (i = 0; i < 10; i++) { //每个哲学家循环一百次后结束
move = '1';
think(); //思考
move = '2';
sleep(1);
Left.get(); //取左筷子
move = '2';
sleep(1);
Right.get(); //取右筷子
move = '3';
eat(); //就餐
Left.put(); //放下左筷子
Right.put(); //放下右筷子
}
move = '0'; //当前线程结束
} catch (InterruptedException e) {
}
}
}
public class Eat {
static wood[] woods = new wood[10];
static People[] people = new People[10];
public static void main(String[] args) {
int i, j = 0, k = 0;
boolean go;
for (i = 0; i < 10; i++) { //初始化每支筷子
woods[i] = new wood(i);
}
for (i = 0; i < 9; i++) { //初试化每个哲学家
people[i] = new People(woods[i], woods[(i + 1) % 10]);
}
// 最后一个哲学家是用第一支和最后一支筷子
people[4] = new People(woods[0], woods[9]);
for (i = 0; i < 10; i++) {
people[i].start();
}
int pro = Thread.currentThread().getPriority() + 1;
Thread.currentThread().setPriority(pro);
go = true;
while (go) {
for (i = 0; i < 10; i++) {
System.out.print(people[i].move); //打印每个线程(哲学家)的状态
}
if (++j % 10 == 0)
System.out.println();
else
go = false;
for (i = 0; i < 10; i++) { //如果都结束,就停止循环.
go = people[i].move != '0'; //当前线程结束
}
try {
Thread.sleep(100); //当前线程休眠100毫秒
} catch (InterruptedException e) {
return;
}
}
}
}
思考了很久,实在不易,希望指正!
以前上课的时候听老师讲过哲学家就餐的问题,当时觉得似懂非懂的,因为对于多线程还不是很了解,现在归纳如下:
哲学家就餐问题是这样的:一圈哲学家就餐,一人左手拿着一支筷子,然后如果他右手边的哲学家给他筷子,他就能就餐,要不就饿死了,这是一个典型的多线程,而且带有死锁的问题。
图示是这样的:
代码示意:
package itheima;
class Test {
public boolean isLocked; //这是线程同步的
public Test() {
isLocked = false;
}
// 同步方法,当筷子必须false才能就餐
public synchronized void lock() throws InterruptedException {
while (isLocked)
wait();
isLocked = true; //锁上可防止同一支筷子被调用
}
public synchronized void unlock() { //解锁
isLocked = false;
notify(); //唤醒别的哲学家
}
}
class wood { //wood表示筷子
public char id; //每支筷子有自己的id
private Test lock = new Test(); //lock用于同步
public void get() throws InterruptedException {
lock.lock(); //筷子调用后加锁
}
public void put() throws InterruptedException {
lock.unlock(); //筷子释放后解锁
}
public wood(int j) { //构造函数
Integer i = new Integer(j);
id = i.toString().charAt(0);
}
}
//People代表哲学家
class People extends Thread {
public char move = '1';
//move代表哲学家的状态
private wood Left, Right; //分别表示左右筷子
// 构造函数,传进当前哲学家用的左右筷子编号
public People(wood left, wood right) {
super();
Left = left;
Right = right;
}
// run函数开始一个线程,代表当前哲学家的活动
public void run() {
int i;
try {
for (i = 0; i < 10; i++) { //每个哲学家循环一百次后结束
move = '1';
think(); //思考
move = '2';
sleep(1);
Left.get(); //取左筷子
move = '2';
sleep(1);
Right.get(); //取右筷子
move = '3';
eat(); //就餐
Left.put(); //放下左筷子
Right.put(); //放下右筷子
}
move = '0'; //当前线程结束
} catch (InterruptedException e) {
}
}
}
public class Eat {
static wood[] woods = new wood[10];
static People[] people = new People[10];
public static void main(String[] args) {
int i, j = 0, k = 0;
boolean go;
for (i = 0; i < 10; i++) { //初始化每支筷子
woods[i] = new wood(i);
}
for (i = 0; i < 9; i++) { //初试化每个哲学家
people[i] = new People(woods[i], woods[(i + 1) % 10]);
}
// 最后一个哲学家是用第一支和最后一支筷子
people[4] = new People(woods[0], woods[9]);
for (i = 0; i < 10; i++) {
people[i].start();
}
int pro = Thread.currentThread().getPriority() + 1;
Thread.currentThread().setPriority(pro);
go = true;
while (go) {
for (i = 0; i < 10; i++) {
System.out.print(people[i].move); //打印每个线程(哲学家)的状态
}
if (++j % 10 == 0)
System.out.println();
else
go = false;
for (i = 0; i < 10; i++) { //如果都结束,就停止循环.
go = people[i].move != '0'; //当前线程结束
}
try {
Thread.sleep(100); //当前线程休眠100毫秒
} catch (InterruptedException e) {
return;
}
}
}
}
思考了很久,实在不易,希望指正!
相关文章推荐
- 初当技术面试官感悟:给面试者的忠告
- 大龄程序员怎样渡过中年危机
- 黑马程序员--java线程总结(三)
- 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】下 ~ Net程序员的福利
- 最近5年133个Java面试问题列表
- 黑马程序员--java线程总结(二)
- 黑马程序员--java线程总结(一)
- 黑马程序员——Java---异常
- 面试被虐,以下近期要提高
- 社会经验-职场经验(以后自己做老板需要警觉)
- sql 经典面试题
- 论程序员的取财之道
- Java并发多线程面试题 Top 50
- 程序员困境(转载至: Medium(by Try Chen))
- 【跟着大磨马学IT编程(安卓java程序员)】第十八天 课程内容概述
- 黑马程序员--基本数据类型总结
- 创意十足的面试,让你成功逆袭,打动HR!
- 创意十足的面试,让你成功逆袭,打动HR!
- 工作一年多了,跳槽,总结下最近面试面试官经常提到的问题,希望能帮到大家
- 有意思的程序员老黄历