生产者和消费者之等待唤醒机制

package test48;

/***
 * 多线程:生产者消费者问题代码
 * 
 * 分析: 资源类:Student 
 * 设置学生数据:SetThread(生产者) 
 * 获取学生数据:GetThread(消费者) 
 * 测试类:StudentDemo
 * 
 * 问题:发现数据每次都是:null---0 
 * 原因:在每个线程中都创建了新的资源,而我们要求的时候设置和获取线程的资源应该是同一个
 * 如何解决:在外界把这个数据创建出来,通过构造方法传递给其他的类。
 * 
 * 问题:为了数据的效果好些,就加入了循环和判断,给出不同的值,这个时候产生新问题 
 * A:同一个数据出现多次B:姓名和年龄不匹配
 * 
 * 原因: A:同一个数据出现多次 
 * CPU的一点点时间片的执行权,就足够你执行很多次。
 *  B:姓名和年龄不匹配 
 *  线程运行的随机性 
 *  
 *  线程安全问题:
 * 是否是多线程环境 是 
 * 是否有共享数据 有
 *  是否有多条语句操作 有
 *  
 *   解决方案:加锁
 *   A:不同种类的线程都要加锁
 *   B:不同种类的线程加的锁必须是同一把。
 *   
 *   
 *   等待唤醒:
 *          Object类中提供了三个方法:
 *              wait():等待
 *              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();
    }
}

// 资源类
class Student {
    String name;
    int age;
    boolean flag;//默认是flase,是没有数据。如果是true,代表有数据。
}

class SetThread implements Runnable {
    private Student s;
    private int x = 0;

    public SetThread(Student s) {
        this.s = s;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (true) {
            synchronized (s) {
                //判断有没有数据
                if(s.flag) {
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                if (x % 2 == 0) {
                    s.name = "白";
                    s.age = 32;
                } else {
                    s.name = "小黑";
                    s.age = 90;
                }
                x++;
                //有就修改标记,并唤醒
                s.flag=true;
                s.notify();
            }
        }
    }
}

class GetThread implements Runnable {
    private Student s;

    public GetThread(Student s) {
        this.s = s;
    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while (true) {
            synchronized (s) {
                if(!s.flag) {
                    try {
                        s.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.out.println(s.name + "---" + s.age);

                //有就消费,然后修改标记,并唤醒线程
                s.flag=false;
                s.notify();
            }
        }

    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰河家园

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值