生产者与消费者

生产者与消费者

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环境中使用

原文地址:https://www.cnblogs.com/mingluosunshan/p/3217404.html