多线程模拟孩子抓糖经典问题
请听题
共11颗糖,有两个小孩,一个小孩一次只能抓三颗糖,另一个小孩一次只能抓四颗糖
如果剩余糖果不够当前小孩拿的数量,当前小孩不在抓糖,请用多线程模拟上面的描述
废话不多说先上码
public class TestFunction {public static volatile AtomicInteger num = new AtomicInteger(11);//孩子线程static class Child extends Thread {private int getR = 0;private int r;CountDownLatch countDownLatch;public Child(int r, CountDownLatch countDownLatch) {this.r = r;this.countDownLatch = countDownLatch;}@Overridepublic String toString() {return "孩子," + "一次拿" + r +"颗糖,共拿了" + getR +"颗糖";}@Overridepublic void run() {try {//等待countDownLatch.await();for (; ; ) {//同步代码快保证原子性,保证判断和计算一致synchronized (num) {if (num.get() >= r) {num.addAndGet(-r);getR += r;} else {return;}}}} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) throws InterruptedException {CountDownLatch countDownLatch = new CountDownLatch(2);Thread thread1 = new Child(3, countDownLatch);thread1.start();countDownLatch.countDown();Thread thread2 = new Child(4, countDownLatch);thread2.start();countDownLatch.countDown();//等待两个线程执行完,回到当前线程thread1.join();thread2.join();System.out.println("剩余糖:" + num);System.out.println(thread1);System.out.println(thread2);}
}
问题解析
可见性
问题可知糖一共有11颗,对于两个孩子都是可见,一个孩子拿完,另外一个孩子是能立马知道的,这就叫可见性。
在代码中普通的参数对于不同线程,在某一个时刻看到值是不一样的。当线程A看到对象是1,其实只是在哪一个时刻看到的缓存区是1,主内存可能已经修改成2。为了避免这种情况。
Java中的volatile 关键字就是为了解决这个问题,当前线程的缓存区的值发生变动时,会第一时间刷入主内存,同时会通知其他使用线程。
锁机制
java中的锁机制JVM来保证数据同步的,而Lock则是在硬件层面,依赖特殊的CPU指令实现数据同步的。
按照题意,在某一个时刻只能有一个线程在进行拿取糖的操作。所需要的对拿取糖的操作进行加锁,保证在任何时刻都只有一个孩子可以拿取糖。这里竞争不不激烈,所以直接使用
synchronized对代码块进行加锁,同时保证数量判断和糖的拿取的原子性。线程等待
因为要模拟糖的拿取,所以我们要保证两个线程同时执行,同时开始拿取糖。所以这个时候CountDownLatch 出现了,在线程中await(),当CountDownLatch 的计数减到0时,所有线程会在继续从await()的下行代码开始执行。所以可以完美的模拟同时拿取的操作。线程同步
当执行所有线程,我为了看到结果使用Thread的join()方法,保证两个孩子线程执行完后,还回到当前主线程。
join()表示将当前线程挂起,等待join的线程执行完,才会回到主线程。
多线程模拟孩子抓糖经典问题相关推荐
- php curl 模拟多线程,php利用curl 多线程 模拟 并发的详解
php利用curl 多线程 模拟 并发的详解 发布于 2014-12-07 10:17:25 | 265 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hypert ...
- python采集直播间数据_Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息示例...
本文实例讲述了Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息.分享给大家供大家参考,具体如下: import time from multiprocessing import Poo ...
- 操作系统课程设计--使用多线程模拟时间片轮转法调度
本篇博文分享操作系统课程设计–使用多线程模拟时间片轮转法调度的思路及代码. 实验环境:虚拟机ubuntu18.04 ,VS Code 博主分享仅为互相学习之用,不懂的地方可以留言提问,谨防抄袭!!!谢 ...
- 利用curl 多线程 模拟 并发的详解
来源:http://www.jb51.net/article/38492.htm 首先,先了解下 php中的curl多线程函数: 复制代码代码如下: # curl_multi_add_handle # ...
- python 模拟浏览器selenium_Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息示例...
本文实例讲述了Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息.分享给大家供大家参考,具体如下: import time from multiprocessing import Poo ...
- java 龟兔赛跑_Java实现多线程模拟龟兔赛跑
Java多线程模拟龟兔赛跑,供大家参考,具体内容如下 笔者利用Java多线程技术,将兔子和乌龟的跑步以两个线程的方式模拟出来,以达到一个初步的效果. 题目如下:路程总距离为35米 兔子:每秒跑5米,每 ...
- Java——使用多线程模拟真实高并发业务并保证安全性(一)
作者专注于Java.架构.Linux.小程序.爬虫.自动化等技术. 工作期间含泪整理出一些资料,微信搜索[javaUp],回复 [java][黑客][爬虫][小程序][面试]等关键字免费获取资料.技术 ...
- 跳妹儿读绘本:我家孩子爱不释手的经典绘本之套装书
上篇分享了我给跳妹儿买书的经验,这里我就来说说这些跳妹儿非常喜欢并点读率高的绘本. 今天分享的主要是套装书,套装书的优点我在之前的文章中有提到过,而且迄今为止我买回来的套装书,每一套我家跳妹儿都非常喜 ...
- python 爬虫动态网页的区别_Python开发爬虫之动态网页抓取篇:爬取博客评论数据——通过Selenium模拟浏览器抓取...
区别于上篇动态网页抓取,这里介绍另一种方法,即使用浏览器渲染引擎.直接用浏览器在显示网页时解析 HTML.应用 CSS 样式并执行 JavaScript 的语句. 这个方法在爬虫过程中会打开一个浏览器 ...
最新文章
- 记忆模糊、记忆泛化的关键分子开关被发现
- 电脑中的php怎么删除文件夹,php中删除文件夹以及文件夹中的文件的方法
- 云速搭部署挂载CPFS的E-HPC
- 理解Joomla!模板
- easyVMAF:在自然环境下运行VMAF
- SQL Server Transactional Replication 中的 CommitBatchSize 和 CommitBatchThreshold 属性
- Android应用开发:CardView的使用及兼容
- 教资科目一要背的内容 0303
- 机器学习笔记II: 决策树
- uploadify 3.2 后台动态传参数
- 如何选择深度学习框架 TensorFlow/Torch/Mxnet/Theano
- 从ST官网获取STM32 AD封装库(包含原理图库和PCB库)详细教程
- 单片机(ISIS 7 Professional):简易8x8矩阵LED灯代码项目
- 申宝公司-两利好提振股市
- JPA-Specification 实现复杂查询
- 特征值和特征值的几何意义
- 游戏语音SDK解决回声消除的方案
- BDP数据可视化分析工具,TAGUL数据可视化分析工具
- elasticsearch 分片(Shards)的理解
- 10大高权重博客_你知道几个?
热门文章
- 怎么样的项目经理才是合格的项目经理?
- 【报告分享】2021颜值经济新消费报告-CBNDATA(附下载)
- EAGLE初体验--SparkFun上学习--电路图制作
- 百度地图 api php,百度地图API使用方法详解
- 光伏并网柜综合监测方案
- VAO VBO IBO的理解
- 大根堆与小根堆的理解,如何手写一个堆,以及什么时候用自己手写的堆,什么时候用语言提供堆的api,(二者的区别)
- Python之冒泡法
- Python全栈开发记录_第七篇(模块_time_datetime_random_os_sys_hashlib_logging_configparser_re)...
- 容器变革应用分发市场