我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java多线程之等待唤醒机制及案例代码演示

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java多线程之等待唤醒机制及案例代码演示

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

等待唤醒机制

生产者和消费者是一个十分经典的多线程协作模式

举个小栗子来说明一下消费者和生产者的等待唤醒过程:
在这里插入图片描述

常见方法

  • void wait() 当前线程等待,直到被其他线程唤醒
  • void notify() 随机唤醒单个线程
  • void notifyAll() 唤醒所有线程

在这里插入图片描述

代码演示

接下来,使用代码来演示生产者和消费者的等待唤醒过程

1、消费者代码:

package com.heima.thread001;public class FoodThread extends Thread {    @Override    public void run() {        while (true){            synchronized (Desk.lock){                if (Desk.count == 0){                    break;                }else {                    //判断桌子上有没有面条                    if (Desk.foodFlag == 0){                        //如果没有,就等待                        try {Desk.lock.wait();//让当前线程跟锁进行绑定                        } catch (InterruptedException e) {e.printStackTrace();                        }                    }else {                        //把吃的总数-1                        Desk.count--;                        //如果有,就开吃                        System.out.println("吃货在吃面条,还能再吃" + Desk.count + "碗");                        //吃完之后,唤醒厨师继续做                        Desk.lock.notifyAll();                        //修改桌子的状态                        Desk.foodFlag = 0;                    }                }            }        }    }}

2、生产者代码

package com.heima.thread001;public class CookThread extends Thread {    @Override    public void run() {        while (true){            synchronized (Desk.lock){                //判断桌子上有没有面条                if (Desk.count == 0){                    break;                }else {                    //判断桌子上是否有实物                    if(Desk.foodFlag == 1){                        //如果有,就等待                        try {Desk.lock.wait();                        } catch (InterruptedException e) {e.printStackTrace();                        }                    }else {                        //如果没有,就制作面条                        System.out.println("厨师做了一碗面条");                        //修改桌子上的食物状态                        Desk.foodFlag = 1;                        //叫醒等待的消费者开吃                        Desk.lock.notifyAll();                    }                }            }        }    }}

3、控制生产者和消费者的执行类

package com.heima.thread001;public class Desk {        //是否有面条  0:没有面条  1:有面条    public static int foodFlag = 0;    //总个数    public static int  count = 10;    //锁对象    public static Object lock = new Object();}

4、测试类

package com.heima.thread001;public class TestDemo {    public static void main(String[] args){        CookThread cookThread = new CookThread();        FoodThread foodThread = new FoodThread();        cookThread.setName("厨师");        foodThread.setName("吃货");        cookThread.start();        foodThread.start();    }}

5、运行结果

Connected to the target VM, address: '127.0.0.1:52025', transport: 'socket'Disconnected from the target VM, address: '127.0.0.1:52025', transport: 'socket'厨师做了一碗面条吃货在吃面条,还能再吃9碗厨师做了一碗面条吃货在吃面条,还能再吃8碗厨师做了一碗面条吃货在吃面条,还能再吃7碗厨师做了一碗面条吃货在吃面条,还能再吃6碗厨师做了一碗面条吃货在吃面条,还能再吃5碗厨师做了一碗面条吃货在吃面条,还能再吃4碗厨师做了一碗面条吃货在吃面条,还能再吃3碗厨师做了一碗面条吃货在吃面条,还能再吃2碗厨师做了一碗面条吃货在吃面条,还能再吃1碗厨师做了一碗面条吃货在吃面条,还能再吃0Process finished with exit code 0

等待唤醒机制(阻塞队列方式实现)

在这里插入图片描述
阻塞队列的继承结构
在这里插入图片描述
代码演示:
生产者代码

package com.heima.thread001;import java.util.concurrent.ArrayBlockingQueue;public class CookThread extends Thread {    ArrayBlockingQueue<String> queue;    public CookThread(ArrayBlockingQueue<String> queue){        this.queue = queue;    }    @Override    public void run() {        while (true){            //不断把面条放到阻塞队列中            try {                queue.put("面条");                System.out.println("厨师放了一碗面条");            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

消费者

package com.heima.thread001;import java.util.concurrent.ArrayBlockingQueue;public class FoodThread extends Thread {    ArrayBlockingQueue<String> queue;    public FoodThread(ArrayBlockingQueue<String> queue){        this.queue = queue;    }    @Override    public void run() {        while (true){            //不断的从阻塞队列中获取面条            try {                String food = queue.take();                System.out.println(food);            } catch (InterruptedException e) {                e.printStackTrace();            }        }    }}

测试类

package com.heima.thread001;import java.util.concurrent.ArrayBlockingQueue;public class TestDemo {    public static void main(String[] args){        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(1);        CookThread c = new CookThread(queue);        FoodThread f = new FoodThread(queue);        c.start();        f.start();    }}

额外扩展

wait()、notify()、notifyAll()方法
Object类里面提供了这几个方法:
wait():让当前线程处于等待(阻塞状态),直到其他线程调用此对象的notify()或notifyAll()方法(进入就绪状态)。
notify():唤醒在此对象监视器上等待的单个线程。
notifyAll():唤醒在此对象监视器上等待的所有线程。
每个方法都有finnal关键字修饰。

为什么这些方法要定义在Object类里,而不定义在Thread类里呢?
因为这些方法的调用必须通过锁对象调用,而锁对象可以是任意对象。所以定义在Object类里。

来源地址:https://blog.csdn.net/weixin_43860634/article/details/133611415

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java多线程之等待唤醒机制及案例代码演示

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解

前言前面的例子都是多个线程在做相同的操作,比如4个线程都对共享数据做tickets–操作。大多情况下,程序中需要不同的线程做不同的事,比如一个线程对共享变量做tickets++操作,另一个线程对共享变量做tickets–操作,这就是大名鼎鼎
2023-05-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录