多线程_生产者消费者之等待唤醒机制代码分析

来源:互联网 发布:ibatis mysql 分页 编辑:程序博客网 时间:2024/05/17 02:16

测试类:StudentDemo

package cn.itcast_05;/* * 分析: * 资源类:Student * 设置学生数据:SetThread(生产者) * 获取学生数据:GetThread(消费者) * 测试类:StudentDemo *  * 问题1:按照思路写代码,发现数据每次都是:null----0 * 原因:我们在每个线程中都创建了新的资源,而我们要求的时候设置和获取线程的资源应该是同一个。 * 如何实现呢? * 在外界把这个数据创建出来,通过构造方法传递给其它的类。 *  * 问题2:为了数据的效果好一些,加入了循环与判断,给出不同的值,这个时候产生了新的问题。 * A:同一个数据出现多次 * B:姓名程年龄不匹配 * 原因: * A:同一个数据出现多次 * CPU一点点时间执行权,就足够你执行很多次。 * B:姓名程年龄不匹配 * 线程运行的随机性 * 线程安全问题: * A:是否是多线程环境是 * B:是否是有共享资源是 * C:是否是多条语句操作共享资源是 * 解决方案: * 加锁。 * 注意: * A:不同种类的线程都要加锁 * B:不同种类的线程加的锁必须是同一把 *  * 问题3:虽然数据安全了,但是呢,一次一大片不好看,我想依次一次一个输出。 * 如何实现呢? * 通过Java提供的等待唤醒机制解决。 *  * 等待唤醒: * Object类提供了三个方法: * wiat():等待 * notify():唤醒单个线程 * notifyAll():唤醒所有线程 * 为什么这些方法不定义在Thread类中呢? * 这些方法的调用必须通过锁对象调用,而我们刚才使用的锁对象是任意锁对象。 * 所以,这些方法必须定义在Object类中。 */public class StudentDemo {public static void main(String[] args) {// 创建资源Student s = new Student();// 设置程获取的类SetThread st = new SetThread(s);GetThread gt = new GetThread(s);// 线程类Thread t1 = new Thread(st);Thread t2 = new Thread(gt);// 启动线程t1.start();t2.start();}}


资源类:Student

package cn.itcast_05;public class Student {String name;int age;boolean flag;//默认情况是没有数据,如果true,说明有数据}


设置学生数据:SetThread(生产者)

package cn.itcast_05;public class SetThread implements Runnable {private Student s;private int x = 0;public SetThread(Student s) {this.s = s;}@Overridepublic void run() {while (true) {synchronized (s) {// 判断有没有if (s.flag) {// true(s.flag)try {s.wait();// t1等着,释放锁} catch (InterruptedException e) {e.printStackTrace();}}if (x % 2 == 0) {s.name = "娄艺萧";s.age = 27;} else {s.name = "曾小贤";s.age = 30;}x++;// 修改标记s.flag = true;// 唤醒线程s.notify();}// t1有或者t2有}}}


获取学生数据:GetThread(消费者)

package cn.itcast_05;public class GetThread implements Runnable {private Student s;public GetThread(Student s) {this.s = s;}@Overridepublic void run() {while (true) {synchronized (s) {if (!s.flag) {// false(!s.flag)try {s.wait();// t2就等待了。立即释放锁。将来醒过来的时候,是从这里醒过来。} catch (InterruptedException e) {e.printStackTrace();}}System.out.println(s.name + "----" + s.age);// 娄艺萧----27// 曾小贤----30// 修改标记s.flag = false;// 唤醒线程s.notify();}}}}


0 0
原创粉丝点击