1116. 打印零与奇偶数

2023-10-26

现有函数 printNumber 可以用一个整数参数调用,并输出该整数到控制台。

例如,调用 printNumber(7) 将会输出 7 到控制台。
给你类 ZeroEvenOdd 的一个实例,该类中有三个函数:zero、even 和 odd 。ZeroEvenOdd 的相同实例将会传递给三个不同线程:

线程 A:调用 zero() ,只输出 0
线程 B:调用 even() ,只输出偶数
线程 C:调用 odd() ,只输出奇数
修改给出的类,以输出序列 "010203040506..." ,其中序列的长度必须为 2n 。

实现 ZeroEvenOdd 类:

ZeroEvenOdd(int n) 用数字 n 初始化对象,表示需要输出的数。
void zero(printNumber) 调用 printNumber 以输出一个 0 。
void even(printNumber) 调用printNumber 以输出偶数。
void odd(printNumber) 调用 printNumber 以输出奇数。
 

示例 1:

输入:n = 2
输出:"0102"
解释:三条线程异步执行,其中一个调用 zero(),另一个线程调用 even(),最后一个线程调用odd()。正确的输出为 "0102"。
示例 2:

输入:n = 5
输出:"0102030405"
 

提示:

1 <= n <= 1000

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/print-zero-even-odd
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路
先前的两道题,我是通过信号量实现的,也考虑过自旋这种模式,但是总超时,后来看到有位朋友在评论谈及可以通过Thread.yeild()释放CPU资源,便茅塞顿开。本题的一种思想其实就是 lock - free

有些知识我们可能知道,但是想不起来用,没关系的。多做几遍就差不多了,就是这些套路。
本题我依然考虑了使用这种线程协作模式。

执行用时:9 ms, 在所有 Java 提交中击败了58.11%的用户
内存消耗:38.8 MB, 在所有 Java 提交中击败了78.02%的用户

初看这题

相同的一个 ZeroEvenOdd 类实例将会传递给三个不同的线程:

线程 A 将调用 zero(),它只输出 0 。
线程 B 将调用 even(),它只输出偶数。
线程 C 将调用 odd(),它只输出奇数。
每个线程都有一个 printNumber 方法来输出一个整数。请修改给出的代码以输出整数序列 010203040506... ,其中序列的长度必须为 2n。

其实本题想表达的意思就是A、B、C三个线程共同的协作,保证:

1.B执行前要A先执行,C执行前要A先执行
2.C要在B执行之前
3.保证输出 n * 2个数(其中有n个0)

说白了就是不管先输出奇数,还是先输出偶数,先输出0。且奇数优先输出于偶数。

那么咱就开始控制这个流程就好了

1.首先执行的是A线程,然后由A线程控制下一个阶段,核心控制
2.由控制器来控制放行的是B还是C。默认


private volatile boolean control = true;
保证C先执行。
3.当C先执行完,将控制器“翻面”,然后回退到A线程去处理。

作者:zong-you-yi-tian
链接:https://leetcode.cn/problems/print-zero-even-odd/solution/qi-shi-tong-xian-qian-liang-dao-ti-yi-yang-wo-men-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    class ZeroEvenOdd {

        private int n;

        private volatile int state;

        private volatile boolean control = true;

        public ZeroEvenOdd(int n) {
            this.n = n;
        }

        public void zero(IntConsumer printNumber) throws InterruptedException {
            for (int i = 0; i < n; i++) {
                while (state != 0) {
                    Thread.yield();
                }
                printNumber.accept(0);
                if (control) {
                    state = 1;
                } else {
                    state = 2;
                }
            }
        }

        public void even(IntConsumer printNumber) throws InterruptedException {
            for (int i = 2; i <= n; i += 2) {
                while (state != 2) {
                    Thread.yield();
                }
                printNumber.accept(i);
                control = true;
                state = 0;
            }
        }

        public void odd(IntConsumer printNumber) throws InterruptedException {
            for (int i = 1; i <= n; i += 2) {
                while (state != 1) {
                    Thread.yield();
                }
                printNumber.accept(i);
                control = false;
                state = 0;
            }
        }
    }

作者:zong-you-yi-tian
链接:https://leetcode.cn/problems/print-zero-even-odd/solution/qi-shi-tong-xian-qian-liang-dao-ti-yi-yang-wo-men-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

改进版本

class ZeroEvenOdd {

        private int n;

        private volatile int state;

        public ZeroEvenOdd(int n) {
            this.n = n;
        }

        public void zero(IntConsumer printNumber) throws InterruptedException {
            for (int i = 0; i < n; i++) {
                while (state != 0) {
                    Thread.yield();
                }
                printNumber.accept(0);
                if (i % 2 == 0) {
        			state = 1;
    			} else {
        			state = 2;
    			}
            }
        }

        public void even(IntConsumer printNumber) throws InterruptedException {
            for (int i = 2; i <= n; i += 2) {
                while (state != 2) {
                    Thread.yield();
                }
                printNumber.accept(i);
                state = 0;
            }
        }

        public void odd(IntConsumer printNumber) throws InterruptedException {
            for (int i = 1; i <= n; i += 2) {
                while (state != 1) {
                    Thread.yield();
                }
                printNumber.accept(i);
                state = 0;
            }
        }
    }

作者:zong-you-yi-tian
链接:https://leetcode.cn/problems/print-zero-even-odd/solution/qi-shi-tong-xian-qian-liang-dao-ti-yi-yang-wo-men-/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

1116. 打印零与奇偶数 的相关文章

随机推荐

  • java生成大小写字母加数字的随机数

    小小的验证码的随机数生成 以前自己一直没有思考过 仔细想想其实实现起来并没有多难 只是自己没有想过这些东西的实现具体应该怎么做比较好 在自己思考后 参考了网上其他作者的一些代码 下面是具体的实现代码 public class Validat
  • LightGBM 原理、代码最全解读!

    来源 Microstrong 本文主要内容概览 1 LightGBM简介 GBDT Gradient Boosting Decision Tree 是机器学习中一个长盛不衰的模型 其主要思想是利用弱分类器 决策树 迭代训练以得到最优模型 该
  • 微信小程序如何访问本地的服务器,springboot2为例

    1 我们需要改一个配置就可以了 以springboot2的项目为例子 2
  • m.777lu.co/wap.php,MaliStore/app.wxss at master · kingpro/MaliStore · GitHub

    src url data font truetype charset utf 8 base64 AAEAAAALAIAAAwAwR1NVQrD s 0AAAE4AAAAQk9TLzJXBku4AAABfAAAAFZjbWFwX864igAA
  • 请问投稿中要求上传的author_SCI投稿过程中主要有哪些状态,持续时间大概多久?...

    原标题 SCI投稿过程中主要有哪些状态 持续时间大概多久 不同出版社旗下SCI杂志的投稿方式 过程以及状态有所区别 但是基本形式大致相同 我们掌握一种杂志的投稿及投稿状态 基本可以以一推百 不同杂志的审稿周期差异比较大 从几天到数月不等 甚
  • ElasticSearch字符串数组类型的精确查询与模糊查询(自定义分词后进行精确与模糊查询)

    一条数据中 有这样的一个字段Keyword Computational devices S models 现需要实现通过分号分词后来查询数据 查询规则如下 1 检索Computational 不区分大小写 时命中结果 2 检索Computa
  • linux中使用crontab设置定时任务

    1 crontab简介 crontab命令常见于 Unix和类Unix 的操作系统之中 用于设置周期性被执行的指令 该命令从标准输入设备读取指令 并将其存放于 crontab 文件中 以供之后读取和执行 crontab储存的指令被守护进程激
  • docker 安装 elasticsearch和kibana(亲测可行)

    1 版本可自己更换 docker pull elasticsearch 6 6 1 2 创建本地挂在目录 mkdir p usr share elasticsearch share config mkdir p usr share elas
  • 用Python完成寻找水仙花数

    首先说一下我是Python的初学者 如果有任何不正确或可以改进的地方 请大家多多包容 所谓 水仙花数 是指一个三位数 其各位数字的立方和等于该数本身 例如153 1 3 5 3 3 3 理解了题意后我们就可以明白找到水仙花的重点就在于将一个
  • R2_A_Taming the Herd

    题面 Taming the Herd Early in the morning Farmer John woke up to the sound of splintering wood It was the cows and they we
  • java中值传递和引用传递

    目录 值传递 引用传递 Java 中有两种数据类型 请谈一下值传递与引用传递 Java 中只有值传递么 值传递 package com github hcsp public class Main public static void mai
  • JAVA单元测试框架-6-Enable priority

    1 enabled属性 在Testng中 如果方法前面添加了 Test注释 然后没有其他的属性 那么默认这个用例会被自动运行 当测试用例没有书写完成 或者不想测试时 可以采用注解 Test enable false 来禁止测试用例的执行 E
  • 如何自学图像编程

    如何自学图像编程 现在 图像类信息越来越多了 对图像的编程需求也越来越多 图像类项目的特点是性价比高 单行代码的价格一般是普通的程序的10倍 每行代码能够卖几块钱 很多人把目光放在这个上面 刚才又有网友咨询 做图像要看些什么书 结合我的自学
  • VSCode打开多个文件时实现标签栏多行显示

    默认情况下 VSCode的标签栏是滚动式的 当打开多个文件时是在同一行中显示的 想要选择查看某个文件时很不方便 如果想要实现多行显示标签页 也是可以的 具体方法如下 操作步骤 1 安装Custom CSS and JS Loader插件 2
  • 相关子查询和不相关子查询

    相关子查询 比如 select t id t name t pass from student t where 80 lt select f score from f where f id t id and f name xxx 这就是1个
  • AICG,人工智能自动生成内容——根据文本生成图像,视频,音频

    文章目录 1 什么是AICG 2 Text2Video 3 Text2Image 4 Text2Audio 5 AICG的发展趋势 1 什么是AICG 什么是AICG AICG是指人工智能自动生成内容 通过算法模型 将文本转化为图像 音频
  • [原]通过GitHub Pages建立个人站点(详细步骤)

    1 Git简介 2 为什么使用Github Pages 3 创建Github Pages 3 1 安装git工具 3 2 两种pages模式 3 3 创建步骤 3 4 常用命令 4 使用Jekyll搭建博客 4 1 什么是jekyll 4
  • 【微信小程序】wx.login 和 wx.getUserProfile 同时使用问题

    场景 在使用微信登录时 通常会在调用 wx login 获取 code 后再通过 wx getUserProfile 获取 iv 和 encryptedData 加密数据 一起发到后端进行登录验证 但是 在实际使用中如果在 wx login
  • HTML+CSS实现按钮居中

    居中的方式有很多 这里以button为例 它是一个行内块级元素display inline block 所以处理方式很简单 可以用以下两种方式 方式一 div style text align center div
  • 1116. 打印零与奇偶数

    现有函数 printNumber 可以用一个整数参数调用 并输出该整数到控制台 例如 调用 printNumber 7 将会输出 7 到控制台 给你类 ZeroEvenOdd 的一个实例 该类中有三个函数 zero even 和 odd Z