生产者与消费者
Object类是所有类的父类,Object类中提供了一下几个方法对线程操作的支持
public final void wait() throws InterruptedException //让一个线程等待
public final void wait(long timeout) throws InterruptedException //线程等待,并指定等待最常毫秒
public final void wait(long timeout,int nanos)throws InterruptedException //线程等待,并指定等待最长毫秒和纳秒
public final void notify() //唤醒第一个等待的进程
public final void notifyAll() //唤醒所有等待的进程
例子:
仓库类:
1 package com.fwj.consumer; 2 3 public class Storage { 4 5 private String name; 6 private boolean flag = true; 7 /* 8 * flag 为true表示仓库为空,可以生产 9 * flag 为false表示仓库已满,可以消费 10 */ 11 public synchronized void set(String name){ 12 if(flag == false){//仓库已满,需要等待 13 try { 14 super.wait();//等待 15 } catch (InterruptedException e) { 16 // TODO Auto-generated catch block 17 e.printStackTrace(); 18 } 19 } 20 try { 21 Thread.sleep(500);//休眠0.5毫秒 22 } catch (InterruptedException e) { 23 // TODO Auto-generated catch block 24 e.printStackTrace(); 25 } 26 this.name = name; 27 System.out.println("生产"+this.name); 28 flag = false;//表示不能生产了,可以消费 29 super.notify();//唤醒其他等待的进程 30 } 31 public synchronized void get(){ 32 if(flag == true){//仓库为空,等待生产 33 try { 34 super.wait();//等待 35 } catch (InterruptedException e) { 36 // TODO Auto-generated catch block 37 e.printStackTrace(); 38 } 39 } 40 try { 41 Thread.sleep(500);//休眠0.5毫秒 42 } catch (InterruptedException e) { 43 // TODO Auto-generated catch block 44 e.printStackTrace(); 45 } 46 System.out.println("消费"+this.name); 47 this.flag = true;//表示不能消费,可以生产了 48 super.notify();//唤醒其他等待进程 49 } 50 }
消费者类:
1 package com.fwj.consumer; 2 3 public class Consumer implements Runnable { 4 5 private Storage st = null; 6 7 public Consumer(Storage st) { 8 super(); 9 this.st = st; 10 } 11 12 @Override 13 public void run() { 14 for(int i=0;i<5;i++) 15 st.get(); 16 } 17 18 }
生产者类:
1 package com.fwj.consumer; 2 3 public class Producer implements Runnable { 4 5 private Storage st = null; 6 7 public Producer(Storage st) { 8 super(); 9 this.st = st; 10 } 11 12 @Override 13 public void run() { 14 for(int i=0;i<5;i++) 15 st.set("商品" + i); 16 } 17 18 }
测试类:
1 package com.fwj.consumer; 2 3 public class Test { 4 5 /** 6 * @param args 7 */ 8 public static void main(String[] args) { 9 Storage sto = new Storage(); 10 Producer p = new Producer(sto); 11 Consumer c = new Consumer(sto); 12 new Thread(p).start(); 13 new Thread(c).start(); 14 } 15 }
运行结果:
生产商品0
消费商品0
生产商品1
消费商品1
生产商品2
消费商品2
生产商品3
消费商品3
生产商品4
消费商品4
this和super
this:它代表当前对象名,在程序中易产生二义性之处,应使用this来指明当前对象;如果函数的形参与类中的成员数据同名,这时需用this来指明成员变量名。
super: 它引用当前对象的直接父类中的成员或方法。
1、super(参数):调用父类中的某一个构造函数(应该为构造函数中的第一条语句)
2、调用super()必须写在子类构造方法的第一行,否则编译不通过。每个子类构造方法的第一条语句,都是隐含地调用super(),如果父类没有这种形式的构造函数,那么在编译的时候就会报错。
3、this(参数):调用本类中另一种形成的构造函数(应该为构造函数中的第一条语句)
4、this()和super()都指的是对象,所以,均不可以在static环境中使用