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

网友投稿 773 2022-10-26

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

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

测试类: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; } @Override public 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; } @Override public 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(); } } }}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:springboot如何通过不同的策略动态调用不同的实现类
下一篇:elemental - 一个灵活的和漂亮的React.js UI框架
相关文章

 发表评论

暂时没有评论,来抢沙发吧~