多线程leetcode编程题

在这里插入图片描述
在这里插入图片描述
synchronized 实现

class ReentrantTest {private  int n;private volatile int flag = 1;private Object lock = new Object();public ReentrantTest(int n) {this.n = n;}public void zero(IntConsumer printNumber) throws InterruptedException{for(int i=1;i<=n;){synchronized (lock){if(flag%4==1 ||flag%4==3){System.out.println(0);flag++;i++;lock.notifyAll();} else{lock.wait();}}}}public void odd(IntConsumer printNumber) throws InterruptedException {for(int i=1;i<=n;){synchronized (lock) {if(flag%4 == 2){System.out.println(i);i = i+2;flag++;lock.notifyAll();} else {lock.wait();}}}}public void even(IntConsumer printNumber) throws InterruptedException{for(int i=2;i<=n;){synchronized (lock) {if(flag%4 == 0){System.out.println(i);i = i+2;flag++;lock.notifyAll();} else {lock.wait();}}}}
}

ReentrantLock+Condition
下面为我第一遍写的错误例子
错误原因,假设先跑zero 线程,执行了 oddCondition.signalAll();后zeroCondition.await();,此时线程释放锁,而后才执行odd()线程,获取锁后oddCondition.await();,由于 .signal只能通知到已经在等待的线程,不能通知未来等待的线程,故,代码卡死了。

class ZeroEvenOdd {private  int n;private   ReentrantLock lock = new ReentrantLock();private  Condition zeroCondition = lock.newCondition();private  Condition evenCondition = lock.newCondition();private  Condition oddCondition = lock.newCondition();public ZeroEvenOdd(int n) {this.n = n;}public void zero() throws InterruptedException {for(int i=1;i<=n;i++){lock.lock();System.out.println(0);if(i%2==1){oddCondition.signalAll();} else {evenCondition.signalAll();}zeroCondition.await();lock.unlock();}}public void even() throws InterruptedException {for(int i=2;i<=n;){lock.lock();evenCondition.await();System.out.println(i);i=i+2;zeroCondition.signalAll();lock.unlock();}}public void odd() throws InterruptedException {for(int i=1;i<=n;){lock.lock();oddCondition.await();System.out.println(i);i=i+2;zeroCondition.signalAll();lock.unlock();}}

修改如下

 class ZeroEvenOdd {private  int n;private   ReentrantLock lock = new ReentrantLock();private  Condition zeroCondition = lock.newCondition();private  Condition evenCondition = lock.newCondition();private  Condition oddCondition = lock.newCondition();private volatile int flag = 1;public ZeroEvenOdd(int n) {this.n = n;}public void zero() throws InterruptedException {for(int i=1;i<=n;){lock.lock();if(flag%4 ==1 || flag%4 == 3){System.out.println(0);flag++;i++;if(flag%4 ==0){evenCondition.signal();} else {oddCondition.signal();}} else {zeroCondition.await();}lock.unlock();}}//偶数public void even() throws InterruptedException {for(int i=2;i<=n;){lock.lock();if(flag%4 ==0){System.out.println(i);i=i+2;flag++;zeroCondition.signal();} else {evenCondition.await();}lock.unlock();}}//奇数public void odd() throws InterruptedException {for(int i=1;i<=n;){lock.lock();if(flag%4 == 2){System.out.println(i);i=i+2;flag++;zeroCondition.signal();} else {oddCondition.await();}lock.unlock();}}}

在这里插入图片描述
在这里插入图片描述
下面这个解的重点是notify 和 notifyAll 的区别

notify和notifyAll的区别
首先讲这俩区别之前先来了解两个概念。锁池EntryList和等待池WaitSet。而这两个池和Object基类的notify

锁池
假设线程A已经拥有了某个对象(不是类)的锁,而其它线程B、C想要调用这个对象的某个synchronized方法(或者代码块), 由于B、C线程在进入对象的synchronized方法(或者块)之前必须先获得该对象锁的拥有权,而恰巧该对象的锁目前正被线程A所占用,此时B、C线程就会被阻塞,进入一个地方去等待锁的释放,这个地方便是该对象的锁池

等待池
假设线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁,同时线程A就进入到了该对象的等待池中,进入到等待池中的线程不会去竞争该对象的锁。

notifyAll会让所有处于等待池的线程全部进入锁池去竞争获取锁的机会
notify只会随机选取一个处于等待池中的线程进入锁池去竞争获取锁的机会

分析:
当current = 1时,执行number()里面,其他线程要么为执行,要么lock.wait();在等待池里,current =3时,number()进入等待池,由于 lock.notifyAll();唤醒了其他几个线程进入锁池,除了fizz满足条件,其他线程都执行了lock.wait();重新进入等待池。

class FizzBuzz {private int n;private final Object lock;private int current;public FizzBuzz(int n) {this.n = n;current = 1;lock = new Object();}// printFizz.run() outputs "fizz".public void fizz(Runnable printFizz) throws InterruptedException {synchronized (lock) {while (current <= n) {if (current % 3 == 0 && current % 5 != 0) {current++;printFizz.run();lock.notifyAll();} else {lock.wait();}}}}// printBuzz.run() outputs "buzz".public void buzz(Runnable printBuzz) throws InterruptedException {synchronized (lock) {while (current <= n) {if (current % 5 == 0 && current % 3 != 0) {current++;printBuzz.run();lock.notifyAll();} else {lock.wait();}}}}// printFizzBuzz.run() outputs "fizzbuzz".public void fizzbuzz(Runnable printFizzBuzz) throws InterruptedException {synchronized (lock) {while (current <= n) {if (current % 15 == 0) {current++;printFizzBuzz.run();lock.notifyAll();} else {lock.wait();}}}}// printNumber.accept(x) outputs "x", where x is an integer.public void number(IntConsumer printNumber) throws InterruptedException {synchronized (lock) {while (current <= n) {if (current % 3 != 0 && current % 5 != 0) {printNumber.accept(current);current++;lock.notifyAll();} else {lock.wait();}}}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis vs memcached

## Redis 和 Memcache 的区别总结 | 特征 | Redis | Memcache | |---|---|---| | 数据结构 | 字符串、哈希表、列表、集合、有序集合、位图 | 字符串 | | 持久化 | 支持 | 不支持 | | 性能 | 整体性能优于 Memcache | 读取简单字符串数据性能略胜一筹 | | 复杂性 | 功能更丰富…

Socket编程权威指南(一)打通网络通信的任督二脉

在网络化的今天&#xff0c;Socket已成为构建分布式系统、实现进程间通信的利器。无论是搭建Web服务器、还是开发网络游戏&#xff0c;Socket编程技能都是必不可少的武器。本文将为你娓娓道来Socket编程的精髓&#xff0c;包括基本流程概览、常用函数剖析&#xff0c;以及精彩实…

如何保证数据库和缓存的数据一致性?

保证数据库和缓存的数据一致性是一个复杂的问题&#xff0c;通常需要根据具体的应用场景和业务需求来设计策略。以下是一些常见的方法来处理数据库和缓存之间的数据一致性问题&#xff1a; 缓存穿透&#xff1a;确保缓存中总是有数据&#xff0c;即使数据在数据库中不存在&…

【CS.CN】优化HTTP传输:揭示Transfer-Encoding: chunked的奥秘与应用

文章目录 0 序言0.1 由来0.2 使用场景 1 Transfer-Encoding: chunked的机制2 语法 && 通过设置Transfer-Encoding: chunked优化性能3 总结References 0 序言 0.1 由来 Transfer-Encoding头部字段在HTTP/1.1中被引入&#xff0c;用于指示数据传输过程中使用的编码方式…

Locust:用Python编写可扩展的负载测试

Locust&#xff1a;简化性能测试&#xff0c;让负载模拟更直观- 精选真开源&#xff0c;释放新价值。 概览 Locust是一个开源的性能和负载测试工具&#xff0c;专门用于HTTP和其他协议的测试。它采用开发者友好的方法&#xff0c;允许用户使用普通的Python代码来定义测试场景。…

nvm,node不是内部命令,npm版本不支持问题(曾经安装过nodejs)

nvm安装后nvm -v有效&#xff0c;node指令无效 环境变量配置无问题 推荐方案 下载你需要的node版本 Index of /dist/ (nodejs.org) 下载后解压到你的nvm存储版本的位置 cmd进入切换你的使用版本&#xff08;此时你的nodejs是从网上下载的&#xff0c;npm文件是存在的&…

Maven中的DependencyManagement和Dependencies

Maven中的DependencyManagement和Dependencies Dependencies Dependencies是Maven项目中用来声明项目依赖的部分。在pom.xml文件中的<dependencies>部分&#xff0c;你可以直接列出项目所依赖的库&#xff08;artifacts&#xff09;。每个依赖通常包括以下信息&#xf…

如何配置Feign以实现服务调试

1、引入依赖 在项目中&#xff0c;需要引入Spring Cloud OpenFeign的依赖。这通常是通过在pom.xml文件中添加相应的Maven依赖来完成的。例如&#xff1a; <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starte…

Python基础知识详解

目录 Python解释器与环境配置 数据类型与结构 控制流语句 文件与IO操作 异常处理机制 函数与模块化编程 Python全栈开发技术栈 Linux环境下的Python开发与自动化 数据分析与挖掘 人工智能与机器学习 自然语言处理 Python知识图谱是指用来组织和展示Python编程语言及…

【PythonCode】力扣Leetcode21~25题Python版

【PythonCode】力扣Leetcode21~25题Python版 前言 力扣Leetcode是一个集学习、刷题、竞赛等功能于一体的编程学习平台&#xff0c;很多计算机相关专业的学生、编程自学者、IT从业者在上面学习和刷题。 在Leetcode上刷题&#xff0c;可以选择各种主流的编程语言&#xff0c;如C…

如何将HTTP升级成HTTPS?既简单又免费的方法!

在当今数字化时代&#xff0c;网络安全已成为用户和企业关注的焦点。HTTPS作为一种更加安全的网络通信协议&#xff0c;正逐渐取代传统的HTTP成为新的标准。对于许多网站管理员和内容创作者来说&#xff0c;如何免费升级到HTTPS是一个值得探讨的问题。本文将详细介绍一些免费的…

一分钟学习数据安全—自主管理身份SSI加密技术

上篇介绍了SSI的架构。架构之后&#xff0c;我们要了解一下SSI发展的驱动力&#xff1a;加密技术。现代数字通信离不开数学和计算机科学&#xff0c;加密技术也源于此。加密技术使区块链和分布式账本得以实现&#xff0c;也使SSI成为可能。 以下我们就概览一下SSI基础架构中涉及…

前端三大主流框架

目录 1.概述 2.React 2.1.作用 2.2.诞生背景 2.3.版本历史 2.4.优缺点 2.5.应用场景 2.6.示例 2.7.未来展望 3.Vue 3.1.作用 3.2.诞生背景 3.3.版本历史 3.4.优缺点 3.5.应用场景 3.7.示例 3.8.未来展望 4.Angular 4.1.作用 4.2.诞生背景 4.3.版本历史 4…

2 程序的灵魂—算法-2.2 简单算法举例-【例 2.5】

【例 2.5】对一个大于或等于 3 的正整数&#xff0c;判断它是不是一个素数。 算法可表示如下&#xff1a; S1: 输入 n 的值 S2: i2 S3: n 被 i 除&#xff0c;得余数 r S4:如果 r0&#xff0c;表示 n 能被 i 整除&#xff0c;则打印 n“不是素数”&#xff0c;算法结束&#xf…

【介绍下R-tree,什么是R-tree?】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

【Java】解决Java报错:ArrayIndexOutOfBoundsException

文章目录 引言1. 错误详解2. 常见的出错场景2.1 直接访问数组越界2.2 循环中的索引错误2.3 多维数组的错误访问 3. 解决方案3.1 检查数组长度3.2 正确使用循环3.3 多维数组的正确访问 4. 预防措施4.1 使用增强型 for 循环4.2 编写防御性代码4.3 单元测试 结语 引言 在Java编程…

力扣面试题17.18.最短超串

力扣面试题17.18.最短超串 类似76. 用哈希表处理短数组 然后遍历长数组 找到相同元素 count– –当count0时进入循环 —— 尽可能缩小区间 class Solution {public:vector<int> shortestSeq(vector<int>& big, vector<int>& small) {int nbig.si…

mysql报错 Duplicate entry

在MySQL中&#xff0c;当你尝试执行插入&#xff08;INSERT&#xff09;或更新&#xff08;UPDATE&#xff09;操作时&#xff0c;如果目标表中存在唯一索引&#xff08;包括主键索引、唯一约束索引等&#xff09;&#xff0c;并且你要插入或更新的数据在该索引列上的值与表中已…

双网卡配置IP和路由总结

1.在网络适配器属性IPv4中设置默认网关&#xff08;记网关地址为A&#xff09;&#xff0c;将会在本地路由表中新增一条记录&#xff1a; 网络号子网掩码网关地址0.0.0.00.0.0.0A 2.如果有两个网卡&#xff08;假设一个连接内网&#xff0c;一个连接互联网&#xff09;&#…

20240607在Toybrick的TB-RK3588开发板的Android12下适配IMX415摄像头和ov50c40

20240607在Toybrick的TB-RK3588开发板的Android12下适配IMX415摄像头和ov50c40 2024/6/7 11:42 【4K/8K摄像头发热量巨大&#xff0c;请做好散热措施&#xff0c;最好使用散热片鼓风机模式&#xff01;】 结论&#xff1a;欢迎您入坑。 Toybrick的TB-RK3588开发板的技术支持不…