请问以下这段程序有什么缺点?为什么没有出现死锁?应该怎么进行修改?
public class kuai { 
String name; boolean Enable = true; public kuai(String name) { 
this.name = name; 
} public synchronized void pickup(){ 
try { 
while(Enable==false){ 
this.wait(); 

this.Enable =false; 

catch (Exception e) { } } public synchronized void putdown() { 
this.Enable =true; 
this.notifyAll(); 
} public static void main(String args[]) { 
kuai k1 = new kuai("筷子1号"); 
kuai k2 = new kuai("筷子2号"); 
kuai k3 = new kuai("筷子3号"); 
kuai k4 = new kuai("筷子4号"); 
kuai k5 = new kuai("筷子5号"); People p1 = new People("老大", k1, k2); 
People p2 = new People("老二", k2, k3); 
People p3 = new People("老三", k3, k4); 
People p4 = new People("老四", k4, k5); 
People p5 = new People("老幺", k5, k1); p1.start(); 
p2.start(); 
p3.start(); 
p4.start(); 
p5.start(); 

} class People extends Thread { 
String name; kuai left; kuai right; public People(String name, kuai l, kuai r) { 
this.name = name; 
left = l; 
right = r; 
} public void run() { 
left.pickup(); 
System.out.println(name + " 眼明手快,以迅雷不及掩耳之势一把抓起 "+left.name); 
right.pickup(); 
System.out.println(name + " 眼明手快,以迅雷不及掩耳之势一把抓起 "+right.name); 
System.out.println(name + " 左右开弓,狼吞虎咽起来"); 
try { 
Thread.sleep(2000); 
} catch (InterruptedException e) { 
// TODO 自动生成 catch 块 
e.printStackTrace(); 

System.out.println(name + " 酒足饭饱,打了个饱嗝,心满意足的放下了 "+left.name+" 和 " +right.name); 
left.putdown(); 
right.putdown(); } 
}

解决方案 »

  1.   

    还有,如果都抢到左筷,而没有抢到右筷,就会出现死锁。比如在拿左筷和拿右筷之间加一个小小的sleep,就会死锁
      

  2.   


    class kuai {
    String name; boolean Enable = true; public kuai(String name) {
    this.name = name;
    } public synchronized void pickup() {
    try {
    while (Enable == false) {
    this.wait();
    }
    this.Enable = false;
    } catch (Exception e) { } } public synchronized void putdown() {
    this.Enable = true;
    this.notifyAll();
    }
    }class People extends Thread {
    String name; kuai left;
    kuai right; public People(String name, kuai l, kuai r) {
    this.name = name;
    left = l;
    right = r;
    } public void run() {
    left.pickup();
    System.out.println(name + "------ " + left.name);
    try{
    Thread.sleep(2000);
    }
    catch(InterruptedException e){
    e.printStackTrace();
    }
    right.pickup();
    System.out.println(name + " ------- " + right.name);
    System.out.println(name + " eating");
    try {
    Thread.sleep(2000);
    } catch (InterruptedException e) { e.printStackTrace();
    }
    System.out.println(name + " over eating " + left.name + " and "
    + right.name);
    left.putdown();
    right.putdown(); }

    public class Test{
    public static void main(String args[]) {
    kuai k1 = new kuai("k1");
    kuai k2 = new kuai("k2");
    kuai k3 = new kuai("k3");
    kuai k4 = new kuai("k4");
    kuai k5 = new kuai("k5"); People p1 = new People("one", k1, k2);
    People p2 = new People("two", k2, k3);
    People p3 = new People("three", k3, k4);
    People p4 = new People("four", k4, k5);
    People p5 = new People("five", k5, k1); p1.start();
    p2.start();
    p3.start();
    p4.start();
    p5.start();
    }
    }
      

  3.   

    1)   上面程序是否真实的模拟的哲学家就餐问题?应如何修改?2)  从Java类设计的角度来看,该程序是否有问题?3)  比较下面的一段Java程序,看两者有什么优缺点?
     class Philosopher extends Thread

     public Philosopher( DiningPhils HOST , int i )
     {
      host = HOST;
      index = i;
     }
     public void setTimeSlice( int TS )
     {
      ts = TS;
     }
     public void setLeftChopstick( boolean flag )
     {
      host.setChopstick(index, flag);
     }
     public void setRightChopstick( boolean flag )
     {
      host.setChopstick((index + 1)% host.getCount() , flag);
     }
     private void releaseChopsticks()
     {
      setLeftChopstick(false);
      setRightChopstick(false);
     }
     public boolean chopsticksFree()
     {
      return !host.getChopstick(index) && 
      !host.getChopstick((index+1)%host.getCount());
     }
     
     public void run()
     {
      while(true)
      {
       grabChopsticks();
       eat();
       think();
      }
     }
     private synchronized void grabChopsticks() /**临界区函数,确保哲学家在没有筷子或筷子不够时思考,满足条件后才就餐*/
     {
      while( !chopsticksFree())
      {
       try
       {
        wait();
       }
       catch( InterruptedException e){}
      }
      takeChopsticks();
      notifyAll();
     }
     private void takeChopsticks()
     {
      setLeftChopstick( true );
      setRightChopstick( true );
      setEat(true);
      host.dumpStatus();
     }
     private void eat()
     {
      pause();
      setEat( false );
      releaseChopsticks();
     }
     private void think()
     {
      pause();
     }
     private void pause()
     {
      setTimeSlice( host.generateTimeSlice());
      try
      {
       sleep(ts*1000);
      }
      catch( InterruptedException e){}
     }
     private void setEat(boolean v)
     {
      isEating = v;
     }
     public boolean getEat()
     {
      return isEating;
     }
     private DiningPhils host;
     private boolean isEating;
     private int index;
     private int ts;
    } import java.util.Random;
    public class DiningPhils
    {
     public static void main(String[] args)
     {
      int n = 10;
      if( n < 1)
      {
       System.err.println( "DiningPils <# of philosophers>" );
       System.exit(-1);
      }
      DiningPhils self = new DiningPhils();
      self.init(n);
     }
     
     public int getCount()
     {
      return n;
     }
     public void setChopstick( int i, boolean v)
     {
      chops[ i ] = v;
     }
     public boolean getChopstick( int i )
     {
      return chops[i];
     }
     
     private void init( final int N)
     {
      r = new Random();
      n = ( N < 0 || N > maxPhils ) ? maxPhils : N;
      chops = new boolean[n];
      phils = new Philosopher[n];
      initPhils();
      dumpStatus();
     }
     private void initPhils()
     {
      for( int i = 0; i< n; i++ )
      {
       phils[i] = new Philosopher( this, i );
       phils[i].setTimeSlice( generateTimeSlice());
       phils[i].setPriority( Thread.NORM_PRIORITY - 1); /**哲学家进程降低一级,使所有哲学家进程 *全部初始化完毕前不会有哲学家进程抢占主线程*/
      }
      while( moreToStart() )
      {
       int i = Math.abs( r.nextInt()) % n;
       if( !phils[i].isAlive())
       {
        System.out.println( " ### Philosopher " +
          String.valueOf( i ) + " started.");
        phils[i].start();
       }
      }
      System.out.println( "\nPhilosophers              Chopsticks"
        + "\n(1 = eating, 0 = thinking)  (1 = taken, 0 = free)");
     }
     public int generateTimeSlice()
     {
      int ts = Math.abs(r.nextInt()) %  (maxEat + 1);
      if( ts == 0 )
       ts = minEat;
      return ts;
     }
     public void dumpStatus()
     {
      for( int i = 0; i < n; i++)
       System.out.print(phils[i].getEat() ? 1 : 0);
      for( int i = n; i < maxPhils + 4; i++ )
       System.out.print(" ");
      for( int i = 0; i < n; i++)
       System.out.print(chops[i]? 1:0);
      System.out.println();
     }
     
     private boolean moreToStart()
     {
      for( int i = 0; i < phils.length; i++ )
      {
       if( !phils[i].isAlive())
        return true;
      }
      return false;
     }
     private int n;
     private Philosopher[] phils;
     private boolean[] chops;
     private Random r;
     private static final int maxPhils = 24;  //最多哲学家数
     private static final int maxEat = 4;   //最多进餐时间 private static final int minEat = 1;   //最少进餐时间
    }