class Chef extends Thread{ Table t; Random r = new Random(12345); public Chef(Table t){ this.t = t; } public void run(){ while(true){ Food f = make(); t.putFood(f); } } private Food make(){ try{ Thread.sleep(200+r.nextInt(200)); }catch(Exception e){} return new Food(); }} 同理我们产生食客类的代码如下:
class Eater extends Thread{ Table t; Random r = new Random(54321); public Eater(Table t){ this.t = t; } public void run(){ while(true){ Food f = t.getFood(); eat(f); } } private void eat(Food f){ try{ Thread.sleep(400+r.nextInt(200)); }catch(Exception e){} }} 完整的程序在这儿:
package debug;import java.util.regex.*;import java.util.*;class Food{}class Table extends LinkedList{ int maxSize; public Table(int maxSize){ this.maxSize = maxSize; } public synchronized void putFood(Food f){ while(this.size() > = this.maxSize){ try{ this.wait(); }catch(Exception e){} } this.add(f); notifyAll(); } public synchronized Food getFood(){ while(this.size() <= 0){ try{ this.wait(); }catch(Exception e){} } Food f = (Food)this.removeFirst(); notifyAll(); return f; }}class Chef extends Thread{ Table t; String name; Random r = new Random(12345); public Chef(String name,Table t){ this.t = t; this.name = name; } public void run(){ while(true){ Food f = make(); System.out.println(name+ " put a Food: "+f); t.putFood(f); } } private Food make(){ try{ Thread.sleep(200+r.nextInt(200)); }catch(Exception e){} return new Food(); }}class Eater extends Thread{ Table t; String name; Random r = new Random(54321); public Eater(String name,Table t){ this.t = t; this.name = name; } public void run(){ while(true){ Food f = t.getFood(); System.out.println(name+ " get a Food: "+f); eat(f); } } private void eat(Food f){ try{ Thread.sleep(400+r.nextInt(200)); }catch(Exception e){} }}public class Test { public static void main(String[] args) throws Exception{ Table t = new Table(10); new Chef( "Chef1 ",t).start(); new Chef( "Chef2 ",t).start(); new Chef( "Chef3 ",t).start(); new Chef( "Chef4 ",t).start(); new Eater( "Eater1 ",t).start(); new Eater( "Eater2 ",t).start(); new Eater( "Eater3 ",t).start(); new Eater( "Eater4 ",t).start(); new Eater( "Eater5 ",t).start(); new Eater( "Eater6 ",t).start(); }}
这一个例子中,我们主要关注以下几个方面:
1.同步方法要保护的对象,本例中是保护桌子,不能同时往上放菜或同时取菜。
假如我们把putFood方法和getFood方法在厨师类和食客类中实现,那么我们应该如此:
(以putFood为例)
class Chef extends Thread{ Table t; String name; public Chef(String name,Table t){ this.t = t; this.name = name; } public void run(){ while(true){ Food f = make(); System.out.println(name+ " put a Food: "+f); putFood(f); } } private Food make(){ Random r = new Random(200); try{ Thread.sleep(200+r.nextInt()); }catch(Exception e){} return new Food(); } public void putFood(Food f){//方法本身不能同步,因为它同步的是this.即Chef的实例 synchronized (t) {//要保护的是t while (t.size() > = t.maxSize) { try { t.wait(); } catch (Exception e) {} } t.add(f); t.notifyAll(); } }} 2.同步的范围,在本例中是放和取两个方法,不能把做菜和吃菜这种各自不相干的工作放在受保护的范围中。