请听题

共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);}
}

问题解析

  1. 可见性

    问题可知糖一共有11颗,对于两个孩子都是可见,一个孩子拿完,另外一个孩子是能立马知道的,这就叫可见性。

    在代码中普通的参数对于不同线程,在某一个时刻看到值是不一样的。当线程A看到对象是1,其实只是在哪一个时刻看到的缓存区是1,主内存可能已经修改成2。为了避免这种情况。

    Java中的volatile 关键字就是为了解决这个问题,当前线程的缓存区的值发生变动时,会第一时间刷入主内存,同时会通知其他使用线程。

  2. 锁机制
    java中的锁机制JVM来保证数据同步的,而Lock则是在硬件层面,依赖特殊的CPU指令实现数据同步的。
    按照题意,在某一个时刻只能有一个线程在进行拿取糖的操作。所需要的对拿取糖的操作进行加锁,保证在任何时刻都只有一个孩子可以拿取糖。这里竞争不不激烈,所以直接使用
    synchronized对代码块进行加锁,同时保证数量判断和糖的拿取的原子性。

  3. 线程等待
    因为要模拟糖的拿取,所以我们要保证两个线程同时执行,同时开始拿取糖。所以这个时候CountDownLatch 出现了,在线程中await(),当CountDownLatch 的计数减到0时,所有线程会在继续从await()的下行代码开始执行。所以可以完美的模拟同时拿取的操作。

  4. 线程同步
    当执行所有线程,我为了看到结果使用Thread的join()方法,保证两个孩子线程执行完后,还回到当前主线程。
    join()表示将当前线程挂起,等待join的线程执行完,才会回到主线程。

多线程模拟孩子抓糖经典问题相关推荐

  1. php curl 模拟多线程,php利用curl 多线程 模拟 并发的详解

    php利用curl 多线程 模拟 并发的详解 发布于 2014-12-07 10:17:25 | 265 次阅读 | 评论: 0 | 来源: 网友投递 PHP开源脚本语言PHP(外文名: Hypert ...

  2. python采集直播间数据_Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息示例...

    本文实例讲述了Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息.分享给大家供大家参考,具体如下: import time from multiprocessing import Poo ...

  3. 操作系统课程设计--使用多线程模拟时间片轮转法调度

    本篇博文分享操作系统课程设计–使用多线程模拟时间片轮转法调度的思路及代码. 实验环境:虚拟机ubuntu18.04 ,VS Code 博主分享仅为互相学习之用,不懂的地方可以留言提问,谨防抄袭!!!谢 ...

  4. 利用curl 多线程 模拟 并发的详解

    来源:http://www.jb51.net/article/38492.htm 首先,先了解下 php中的curl多线程函数: 复制代码代码如下: # curl_multi_add_handle # ...

  5. python 模拟浏览器selenium_Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息示例...

    本文实例讲述了Python使用Selenium模块模拟浏览器抓取斗鱼直播间信息.分享给大家供大家参考,具体如下: import time from multiprocessing import Poo ...

  6. java 龟兔赛跑_Java实现多线程模拟龟兔赛跑

    Java多线程模拟龟兔赛跑,供大家参考,具体内容如下 笔者利用Java多线程技术,将兔子和乌龟的跑步以两个线程的方式模拟出来,以达到一个初步的效果. 题目如下:路程总距离为35米 兔子:每秒跑5米,每 ...

  7. Java——使用多线程模拟真实高并发业务并保证安全性(一)

    作者专注于Java.架构.Linux.小程序.爬虫.自动化等技术. 工作期间含泪整理出一些资料,微信搜索[javaUp],回复 [java][黑客][爬虫][小程序][面试]等关键字免费获取资料.技术 ...

  8. 跳妹儿读绘本:我家孩子爱不释手的经典绘本之套装书

    上篇分享了我给跳妹儿买书的经验,这里我就来说说这些跳妹儿非常喜欢并点读率高的绘本. 今天分享的主要是套装书,套装书的优点我在之前的文章中有提到过,而且迄今为止我买回来的套装书,每一套我家跳妹儿都非常喜 ...

  9. python 爬虫动态网页的区别_Python开发爬虫之动态网页抓取篇:爬取博客评论数据——通过Selenium模拟浏览器抓取...

    区别于上篇动态网页抓取,这里介绍另一种方法,即使用浏览器渲染引擎.直接用浏览器在显示网页时解析 HTML.应用 CSS 样式并执行 JavaScript 的语句. 这个方法在爬虫过程中会打开一个浏览器 ...

最新文章

  1. 记忆模糊、记忆泛化的关键分子开关被发现
  2. 电脑中的php怎么删除文件夹,php中删除文件夹以及文件夹中的文件的方法
  3. 云速搭部署挂载CPFS的E-HPC
  4. 理解Joomla!模板
  5. easyVMAF:在自然环境下运行VMAF
  6. SQL Server Transactional Replication 中的 CommitBatchSize 和 CommitBatchThreshold 属性
  7. Android应用开发:CardView的使用及兼容
  8. 教资科目一要背的内容 0303
  9. 机器学习笔记II: 决策树
  10. uploadify 3.2 后台动态传参数
  11. 如何选择深度学习框架 TensorFlow/Torch/Mxnet/Theano
  12. 从ST官网获取STM32 AD封装库(包含原理图库和PCB库)详细教程
  13. 单片机(ISIS 7 Professional):简易8x8矩阵LED灯代码项目
  14. 申宝公司-两利好提振股市
  15. JPA-Specification 实现复杂查询
  16. 特征值和特征值的几何意义
  17. 游戏语音SDK解决回声消除的方案
  18. BDP数据可视化分析工具,TAGUL数据可视化分析工具
  19. elasticsearch 分片(Shards)的理解
  20. 10大高权重博客_你知道几个?

热门文章

  1. 怎么样的项目经理才是合格的项目经理?
  2. 【报告分享】2021颜值经济新消费报告-CBNDATA(附下载)
  3. EAGLE初体验--SparkFun上学习--电路图制作
  4. 百度地图 api php,百度地图API使用方法详解
  5. 光伏并网柜综合监测方案
  6. VAO VBO IBO的理解
  7. 大根堆与小根堆的理解,如何手写一个堆,以及什么时候用自己手写的堆,什么时候用语言提供堆的api,(二者的区别)
  8. Python之冒泡法
  9. Python全栈开发记录_第七篇(模块_time_datetime_random_os_sys_hashlib_logging_configparser_re)...
  10. 容器变革应用分发市场