标签:
一、生产者消费者模式的学生类成员变量生产与消费demo,第一版
1、等待唤醒:
Object类中提供了三个方法:
wait():等待
notify():唤醒单个线程
notifyAll():唤醒所有线程
2、为什么这些方法不定义在Thread类中呢?
这些方法的调用必须通过锁对象调用,而我们刚才使用的锁对象是任意锁对象。
所以,这些方法必须定义在Object类中。
3、当我们在使用多线程的时候有的时候需要,一条线程产生一个数据,另一条线程接着消费一个数据,一边生产一边消费,既没有多余的数据产生,也没有的空的数据被消费。
4、问题解决方案第一步保证线程同步安全:(1)加锁,
A:不同种类的线程都要加锁。
B:不同种类的线程加的锁必须是同一把。
5、问题解决方案第二步保证数据的一次生产消费:(等待唤醒机制)。
6、在下面新建的两条线程,两条线程操作的对象都是学会类,一条线程生产学生对象的数据,一条线程消费学生对象的数据,且做到,有数据才消费,没数据就等待,没数据就生产,有数据就等待。
//==========================
//第一个案例是学生类对象,非常的简单就定义了两个成员变量,以及一个用于唤醒线程的标记。
1 public class Student { 2 public String name; 3 public int age; 4 boolean flag; //默认情况是false--->没有数据,如果是true说明有数据。 5 6 }
//下面的是生产者学生对象的demo
//在构造方法中传递了学生对象,保证生产者与消费者操作的是同一个对象。
1 public class setThread implements Runnable { 2 private Student s; 3 int x = 0; 4 5 public setThread(Student s) { 6 this.s = s; 7 } 8 9 @Override 10 public void run() { 11 while (true) { 12 synchronized (s) { 13 // 唤醒机制,生产者,先判断有没有哦,有就等待被消费,没有就生产数据准备被消费。 14 if (s.flag) { 15 try { 16 s.wait(); 17 } catch (InterruptedException e) { 18 // TODO Auto-generated catch block 19 e.printStackTrace(); 20 } 21 } 22 23 //一旦flag标记为false就执行下面的代码 24 25 if (x % 2 == 0) { 26 s.name = "java"; 27 s.age = 25; 28 } else { 29 s.name = "android"; 30 s.age = 20; 31 } 32 x++; 33 // 数据生产一次,此时有了数据需要修改标记,下一循环开始的时候,就暂时不在生产, 34 s.flag = true; 35 36 // 唤醒线程 37 s.notify(); 38 } 39 40 } 41 } 42 43 }
//下面的是学生对象的消费者模式demo
//在构造方法中传递了学生对象,保证生产者与消费者操作的是同一个对象。
1 public class getThread implements Runnable { 2 private Student s; 3 4 public getThread(Student s) { 5 this.s = s; 6 } 7 8 public void run() { 9 while (true) { 10 // 唤醒机制 消费者,有数据就消费,没有数据(!)就等待数据被生产。 11 // 吐过没有就等待,有就消费 12 synchronized (s) { 13 if (!s.flag) { //flag--->false执行if下面的代码:表示没有数据就等待 14 try { 15 s.wait(); //在等待的时候立即释放锁,方便其他的线程使用锁。而且被唤醒时,就在此处唤醒, 16 } catch (InterruptedException e) { 17 // TODO Auto-generated catch block 18 e.printStackTrace(); 19 } 20 } 21 22 // flag--->true:消费数据 23 System.out.println(s.name + " " + s.age); 24 // 消费完毕后,数据没有了,修改标记 25 s.flag = false; 26 // 唤醒线程 27 //唤醒并不代表你立即可以得到执行权,此时仍然需要抢CPU的执行权, 28 s.notify(); 29 } 30 } 31 } 32 }
//下面的是测试用例,就是简单的创建了两条线程,然后启动刚才的生产者与消费者
1 /* 2 * 如何在同一个包下,多个类中共享一个数据: 3 * 在外界把这个数据创建出来,然后通过构造方法传递给其它的类。 4 */ 5 public class Demo { 6 public static void main(String[] args) { 7 // 共享数据,外界创建,作为参数,通过构造共有 8 Student s = new Student(); 9 // 在构造中使用同一个参数 10 setThread st = new setThread(s); 11 getThread gt = new getThread(s); 12 13 Thread t1 = new Thread(st);// 设置数据 14 Thread t2 = new Thread(gt); // 获取数据 15 16 t2.start(); 17 t1.start(); 18 19 } 20 }
java多线程中的生产者与消费者之等待唤醒机制@Version1.0
标签:
原文地址:http://www.cnblogs.com/fuck1/p/5432634.html