线程交互现象

线程交互现象

小明对自家的狗子有个规定,就是在狗狗还没吃完的时候,可以继续给他加饭

不好的解决方式

狗狗感觉一千年没吃饭了,狼吞虎咽起来,最后饭只剩下最后一点点,吃饭线程中使用while循环判断是否是1,如果是1那么就一直循环,知道加饭又重新回到了起点,这虽然是狗狗能够吃的更多,那么狗狗也会长得太胖了,太胖对狗狗健康有威胁,所以是一个不好的解决方式。

package multiThread2;

public class test {
    public static void main(String[] args) {
        Animal a = new Animal("大黄", 3, 10);
        Thread t1 = new Thread(){
            @Override
            public void run() {
                while (true){
                    while (a.getFood()==1){
                        continue;
                    }
                    a.eatFood();
                    System.out.println(a.getName()+"吃饭,剩余"+a.getFood());
                    try {
                        Thread.sleep(1);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        };
        t1.start();
        Thread t2 = new Thread(){
            @Override
            public void run() {
                while (true){
                    a.addFood();
                    System.out.println(a.getName()+"加饭,剩余"+a.getFood());
                    try {
                        Thread.sleep(100);//这里注意,时间必须比上面多,不然无法看见饭剩下1
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                }
            }
        };
        t2.start();
    }
}
package multiThread2;

public class Animal{
    private String name;
    private int year;
    Animal(){}
    private int food;
    public Animal(String name,int year,int food){
        this.name = name;
        this.year = year;
        this.food = food;
    }

    @Override
    public String toString() {
        return "姓名:"+ name + ",年龄:" + year + ",来干饭了,还剩"+ food + "个食物";
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getFood() {
        return food;
    }

    public void setFood(int food) {
        this.food = food;
    }
    public synchronized void eatFood(){
        synchronized(this) {
            this.food--;
        }
    }
    public void addFood(){
        synchronized (this) {
            this.food++;
        }
    }
}

在这里插入图片描述

使用wait和notify进行线程交互

在Animal类中,eatfood方法,当food==1时,执行this.wait()
this.wait()指的是暂停执行,释放占有
进入eatfood方法,使用this.wait()可以让吃食物线程临时释放对this的占有,这样就有机会进入addfood方法了
addfood:增加食物之后,执行this.notify
this.notify表示通知等待this的线程,可以苏醒过来了。等待在this的线程,是吃饭过程。一旦addfood()结束,加食物线程释放了this,吃食物线程,重新占有this,执行后面的吃食物工作。

package multiThread2;

public class Animal{
   private String name;
   private int year;
   Animal(){}
   private int food;
   public Animal(String name,int year,int food){
       this.name = name;
       this.year = year;
       this.food = food;
   }

   @Override
   public String toString() {
       return "姓名:"+ name + ",年龄:" + year + ",来干饭了,还剩"+ food + "个食物";
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public int getYear() {
       return year;
   }

   public void setYear(int year) {
       this.year = year;
   }

   public int getFood() {
       return food;
   }

   public void setFood(int food) {
       this.food = food;
   }
   public synchronized void eatFood(){
       if(food==1) {
           try{
               this.wait();
           }catch (InterruptedException e){
               e.printStackTrace();
           }
           this.food--;
       }
   }
   public synchronized void addFood(){
       this.food++;
       this.notify();
   }
}
package multiThread2;

public class test {
   public static void main(String[] args) {
       Animal a = new Animal("大黄", 3, 10);
       Thread t1 = new Thread(){
           @Override
           public void run() {
               while (true){
//                    while (a.getFood()==1){
//                        continue;
//                    }
                   a.eatFood();
                   System.out.println(a.getName()+"吃饭,剩余"+a.getFood());
                   try {
                       Thread.sleep(1);
                   }catch (InterruptedException e){
                       e.printStackTrace();
                   }
               }
           }
       };
       t1.start();
       Thread t2 = new Thread(){
           @Override
           public void run() {
               while (true){
                   a.addFood();
                   System.out.println(a.getName()+"加饭,剩余"+a.getFood());
                   try {
                       Thread.sleep(100);
                   }catch (InterruptedException e){
                       e.printStackTrace();
                   }
               }
           }
       };
       t2.start();
   }
}

在这里插入图片描述
这里需要强调的是,wait方法和notify方法,并不是Thread线程上的方法,它们是Object上的方法。
因为所有的Object都可以被用来作为同步对象,所以准确的讲,wait和notify是同步对象上的方法。
wait()的意思是: 让占用了这个同步对象的线程,临时释放当前的占用,并且等待。 所以调用wait是有前提条件的,一定是在synchronized块里,否则就会出错。
notify() 的意思是,通知一个等待在这个同步对象上的线程,你可以苏醒过来了,有机会重新占用当前对象了。
notifyAll() 的意思是,通知所有的等待在这个同步对象上的线程,你们可以苏醒过来了,有机会重新占用当前对象了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/786395.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ST Smart Things Sentinel:一款针对复杂IoT协议的威胁检测工具

关于ST Smart Things Sentinel ST Smart Things Sentinel,简称ST,是一款功能强大的安全工具,广大研究人员可以使用该工具检测物联网 (IoT) 设备使用的复杂协议中的安全威胁。 在不断发展的联网设备领域,ST Smart Things Sentinel…

轮转数组(反转数组)的实现,看这篇就够了!!

一:题目 本题用数组为1 2 3 4 5 6 7 k3 来进行举例 理想结果为:5 6 7 1 2 3 4 二:思路 第一种方法: 用memcpy函数来实现 第一步:用malloc开辟一个新数组 第二步:将5 6 7 放进新数组 第三步&…

【JS|第21期】JavaScript模块化:深入解析三种文件暴露方式

日期:2024年7月6日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方,还望各位大佬不吝赐教,谢谢^ - ^ 1.01365 = 37.7834;0.99365 = 0.0255 1.02365 = 1377.4083…

台灯护眼是真的吗?台灯怎么选对眼睛好?一文带你读懂!

近视问题,这一现代社会的“视力杀手”,正悄然影响着越来越多的人群,尤其是青少年群体。长时间面对电子屏幕和书本,加上不正确的用眼习惯,使得视力下降成为普遍现象。在此背景下,一款优质的护眼台灯显得尤为…

【机器学习】Exam3

线性可分logistic逻辑回归 数据集点被分为了两边,根据课程学会归一化函数以及梯度下降即可。 使用线性模型。 import copyimport numpy as np import pandas as pd from matplotlib import pyplot as plt#归一化函数 def sigmoid(x):return 1 / (1 np.exp(-x))# …

基于Python的51job招聘数据采集与可视化项目实践

项目背景与目标 在当今竞争激烈的就业市场中,深入分析招聘信息对于求职者和企业都具有重要意义。基于Python的51job招聘数据采集与可视化项目旨在通过自动化手段高效获取大量招聘信息,并对这些数据进行深度分析和展示。 51job作为中国领先的招聘网站&…

ALG:MODTRAN查找表参数详解(学习笔记4)

一、Modtran安装及环境配置 https://blog.csdn.net/qq_41358707/article/details/134721973 二、ALG配置更新 添加大气RTM。Settings,进入首选项界面,单击RTM选项卡以更新RTM的配置: 从窗口右上角的select RTM弹出菜单中选择一个大气RTM&a…

Docker Desktop如何换镜像源?

docker现在很多镜像源都出现了问题,导致无法拉取镜像,所以找到一个好的镜像源,尤为重要。 一、阿里镜像源 经过测试,目前,阿里云镜像加速地址还可以使用。如果没有阿里云账号,需要先注册一个账号。 地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 二…

【AI前沿】人工智能的历史演进

文章目录 📑引言一、人工智能的起源与早期发展1.1 古代与早期的智能机器设想1.2 20世纪初期的机械计算机1.3 图灵测试与计算智能1.4 达特茅斯会议与人工智能的正式诞生 二、早期AI研究与第一次冬天2.1 早期的探索与挑战2.2 早期的专家系统2.3 第一次AI冬天 三、专家…

C++杂说- 多态和继承的知识在总结

多态 就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会 产生出不同的状态。 构成多态还有两个条件: 1. 必须通过基类的指针或者引用调用虚函数 2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写 虚…

67.SAP FICO-凭证类型学习

目录 SAP凭证类型 凭证类型的作用 - OBA7 SAP默认的凭证类型更改 FI相应事务代码默认凭证类型 - OBU1 对FB50、60、70默认凭证类型的更改 - OBZO 后勤货物移动默认凭证类型 - OMBA 发货凭证类型 收货凭证类型 自动移动凭证类型 存货盘点凭证类型 发票默认的凭证类…

vue3中使用provide跨层传值(方法)

1.使用provide inject 跨层实现 祖父组件: provide有两个参数,第一个是我们传递的key,第二个就是value了 孙子组件: const dataList inject(getDataList1)//使用inject接收 const dataList1 dataList.getDataList 页面中使…

制作问卷表单二维码的方法,扫码登记信息更快捷

为了更好地收集用户信息,现在很多场景下会使用生成二维码的方式,让用户可以扫码自行填写相关信息,从而提高获取信息的效率以及填写数据的便捷性。那么用于收集用户数据的表单二维码是如何生成的呢?其实方法很简单,现在…

2.pwn的linux基础(计算机内部数据结构存储形式)

linux基础 保护层级: 分为四个ring0-ring3 一般来说就两个,0和3 0为内核 3为用户 权限: 用户分为多个组 文件和目录等等的权限一般都是三个,即可读可写可执行。 读:R,写:W,执行:X 赋予一个可执行文件执行权限就是chmod x file…

KBPC5010-ASEMI逆变焊机专用KBPC5010

编辑:ll KBPC5010-ASEMI逆变焊机专用KBPC5010 型号:KBPC5010 品牌:ASEMI 封装:KBPC-4 正向电流(Id):50A 反向耐压(VRRM):1000V 正向浪涌电流&#xff…

Vue89-Vuex中多组件共享数据

一、需求 1-1、count组件读取persons数据 借助mapState映射。 1-2、personList组件读取sum数据

MoRA: High-Rank Updating for Parameter-Efficient Fine-Tuning

文章汇总 LoRA的问题 与FFT相比,低秩更新难以记忆新知识。虽然不断提高LoRA的秩可以缓解这一问题,但差距仍然存在。 动机 尽可能地利用相同的可训练参数来获得更高的 Δ W \Delta W ΔW秩。 考虑到预训练权值 W 0 ∈ R d k W_0\in R^{d\times k} W0​…

【HTML入门】第五课 - 加粗和倾斜的字体们

这一小节,我们说一些常用的HTML文本格式化的标签知识。可能你会觉得HTML知识比较零散,有好多标签。没错,就是比较零散,标签比较多。正式这些形形色色的HTML标签们,组成了丰富多彩的网页元素。 但是在刚学习的时候&…

Linux-gdb

目录 1.-g 生成含有debug信息的可执行文件 2.gdb开始以及gdb中的常用执行指令 3.断点的本质用法 4.快速跳出函数体 5.其他 1.-g 生成含有debug信息的可执行文件 2.gdb开始以及gdb中的常用执行指令 3.断点的本质用法 断点的本质是帮助我们缩小出问题的范围 比如,…

three-platformize 微信小程序 uniapp 使用截图功能

最近需要将3d场景进行截图,但是网上的各种各样,看的我一团乱麻,因此在解决完后就将这些简单的分享一下; 原理:将3维场景的那个canvas中的像素提取出来,找一个空的canvas二维画布放上去,然后用二…