Chinaunix首页 | 论坛 | 博客
  • 博客访问: 178430
  • 博文数量: 89
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 828
  • 用 户 组: 普通用户
  • 注册时间: 2013-10-08 10:44
文章分类
文章存档

2014年(9)

2013年(80)

我的朋友

分类: Java

2013-10-15 18:06:46

问题描述:假设有5个哲学家,他们把一生都拿来思考和吃饭。他们共用一个圆桌吃饭,有一锅米饭,每个人两边有两根筷子。当某位哲学家思考时,他与其他同事不交互。时而,他会感到饥饿,并试图拿起与他相近的左右两根筷子。当5个哲学家同时饥饿,且同时那起一根的筷子,他们会永远等待,陷入死锁。就算没有发生死锁,也会发生“资源耗尽”。
分析:这是一个需要在多个进程之间分配多个资源且不会出现死锁和饥饿的典型例子。
(死锁4个条件:1、互斥访问;2、请求保持;3、非剥夺;4、环路等待
而解决死锁方法主要是死锁预防,即打破死锁必要条件中的一个。)




黑色数字:代表哲学家序号;
红色数字:代表筷子序号;
而我对这个问题是这么看的:哲学家们先左手拿起筷子,然后再右手拿起筷子,当两个手都有筷子了,就可以进食了(我设定每个人进食时间都是随机不同),然后再放下筷子。应该预防的问题是产生死锁:比如每个哲学家左手都拿起左手边的筷子,没人肯放下筷子,造成谁都吃不了饭。




而我的具体代码如下:
Philosopher.java
[java] view plaincopyprint?
public class Philosopher extends Thread {  
  
    private final int man_id;  
    private Chopsticks cho_right, cho_left;  
    private boolean b1, b2;  
    private static final String HAND_LEFT = "左手",  
                                HAND_RIGHT = "右手";  
  
    public Philosopher(int man_id, Chopsticks cho_right, Chopsticks cho_left) {  
        this.man_id = man_id;  
        this.cho_right = cho_right;  
        this.cho_left = cho_left;  
        setName("哲学家" + man_id + "号");  
    }  
  
    public void run() {  
        while (true) {  
            synchronized (cho_right) {  
                synchronized (cho_left) {  
                    cho_left.pickUp(HAND_LEFT);  
                    cho_left.notify();  
                }  
                try {  
                    cho_right.wait();  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
                cho_right.pickUp(HAND_RIGHT);  
                System.out.println(Thread.currentThread().getName()  
                        + "正在进食...");  
                try {  
                    Thread.currentThread().sleep(new Random().nextInt(3)*1000);  
                } catch (InterruptedException e) {  
                    e.printStackTrace();  
                }  
                cho_left.putDown(HAND_LEFT);  
                cho_right.putDown(HAND_RIGHT);  
            }  
        }  
    }  
  
}  


Chopsticks.java
[java] view plaincopyprint?
public class Chopsticks {  
  
    private final int ID;  
  
    public Chopsticks(int ID) {  
        this.ID = ID;  
    }  
  
    public synchronized void pickUp(String hand) {  
        System.out.println(Thread.currentThread().getName()  
                            + hand + "拿起筷子" + this.getId() + "号");  
    }  
  
    public synchronized void putDown(String hand) {  
        System.out.println(Thread.currentThread().getName()  
                + hand + "放下筷子" + this.getId() + "号");  
    }  
      
    public int getId() {  
        return ID;  
    }  
  
}  


PhilosophersEat.java
[java] view plaincopyprint?
public class PhilosophersEat {  
      
    public static void main(String[] args) {  
        Chopsticks c0 = new Chopsticks(0);  
        Chopsticks c1 = new Chopsticks(1);  
        Chopsticks c2 = new Chopsticks(2);  
        Chopsticks c3 = new Chopsticks(3);  
        Chopsticks c4 = new Chopsticks(4);  
          
        Philosopher p0 = new Philosopher(0, c4, c0);  
        Philosopher p1 = new Philosopher(1, c0, c1);  
        Philosopher p2 = new Philosopher(2, c1, c2);  
        Philosopher p3 = new Philosopher(3, c2, c3);  
        Philosopher p4 = new Philosopher(4, c3, c4);  
          
        p0.start();  
        p1.start();  
        p2.start();  
        p3.start();  
        p4.start();  
          
    }  
      
}  

阅读(573) | 评论(0) | 转发(0) |
0

上一篇:Java 二分查找算法

下一篇:JDBC批处理

给主人留下些什么吧!~~