当前位置: 首页 > news >正文

安徽智农网络信息技术服务有限公司 网站开发手机网站会员识别功能

安徽智农网络信息技术服务有限公司 网站开发,手机网站会员识别功能,做网站常用的jquery,献县制作网站前言 较长一段时间以来我都发现不少开发者对 jdk 中的 J.U.C#xff08;java.util.concurrent#xff09;也就是 Java 并发包的使用甚少#xff0c;更别谈对它的理解了#xff1b;但这却也是我们进阶的必备关卡。 之前或多或少也分享过相关内容#xff0c;但都不成体系java.util.concurrent也就是 Java 并发包的使用甚少更别谈对它的理解了但这却也是我们进阶的必备关卡。 之前或多或少也分享过相关内容但都不成体系于是便想整理一套与并发包相关的系列文章。 其中的内容主要包含以下几个部分 根据定义自己实现一个并发工具。JDK 的标准实现。实践案例。基于这三点我相信大家对这部分内容不至于一问三不知。 既然开了一个新坑就不想做的太差所以我打算将这个列表下的大部分类都讲到。 所以本次重点讨论 ArrayBlockingQueue。 自己实现 在自己实现之前先搞清楚阻塞队列的几个特点 基本队列特性先进先出。写入队列空间不可用时会阻塞。获取队列数据时当队列为空时将阻塞。实现队列的方式多种总的来说就是数组和链表其实我们只需要搞清楚其中一个即可不同的特性主要表现为数组和链表的区别。 这里的 ArrayBlockingQueue 看名字很明显是由数组实现。 我们先根据它这三个特性尝试自己实现试试。 初始化队列 我这里自定义了一个类ArrayQueue它的构造函数如下 public ArrayQueue(int size) {items new Object[size];} 很明显这里的 items 就是存放数据的数组在初始化时需要根据大小创建数组。 写入队列 写入队列比较简单只需要依次把数据存放到这个数组中即可如下图 但还是有几个需要注意的点 队列满的时候写入的线程需要被阻塞。写入过队列的数量大于队列大小时需要从第一个下标开始写。先看第一个队列满的时候写入的线程需要被阻塞先来考虑下如何才能使一个线程被阻塞看起来的表象线程卡住啥事也做不了。 有几种方案可以实现这个效果: Thread.sleep(timeout)线程休眠。object.wait() 让线程进入 waiting 状态。 当然还有一些 join、LockSupport.part 等不在本次的讨论范围。 阻塞队列还有一个非常重要的特性是当队列空间可用时取出队列写入线程需要被唤醒让数据可以写入进去。 所以很明显Thread.sleep(timeout)不合适它在到达超时时间之后便会继续运行达不到空间可用时才唤醒继续运行这个特点。 其实这样的一个特点很容易让我们想到 Java 的等待通知机制来实现线程间通信更多线程见通信的方案可以参考这里深入理解线程通信 所以我这里的做法是一旦队列满时就将写入线程调用 object.wait() 进入 waiting 状态直到空间可用时再进行唤醒。 /*** 队列满时的阻塞锁*/private Object full new Object();/*** 队列空时的阻塞锁*/private Object empty new Object(); 所以这里声明了两个对象用于队列满、空情况下的互相通知作用。 在写入数据成功后需要使用 empty.notify()这样的目的是当获取队列为空时一旦写入数据成功就可以把消费队列的线程唤醒。 这里的 wait 和 notify 操作都需要对各自的对象使用 synchronized 方法块这是因为 wait 和 notify 都需要获取到各自的锁。 消费队列 上文也提到了当队列为空时获取队列的线程需要被阻塞直到队列中有数据时才被唤醒。 代码和写入的非常类似也很好理解只是这里的等待、唤醒恰好是相反的通过下面这张图可以很好理解 总的来说就是 写入队列满时会阻塞直到获取线程消费了队列数据后唤醒写入线程。消费队列空时会阻塞直到写入线程写入了队列数据后唤醒消费线程。测试 先来一个基本的测试单线程的写入和消费。 3 123 1234 12345 通过结果来看没什么问题。 当写入的数据超过队列的大小时就只能消费之后才能接着写入。 2019-04-09 16:24:41.040 [Thread-0] INFO c.c.concurrent.ArrayQueueTest - [Thread-0]123 2019-04-09 16:24:41.040 [main] INFO c.c.concurrent.ArrayQueueTest - size3 2019-04-09 16:24:41.047 [main] INFO c.c.concurrent.ArrayQueueTest - 1234 2019-04-09 16:24:41.048 [main] INFO c.c.concurrent.ArrayQueueTest - 12345 2019-04-09 16:24:41.048 [main] INFO c.c.concurrent.ArrayQueueTest - 123456 从运行结果也能看出只有当消费数据后才能接着往队列里写入数据。 而当没有消费时再往队列里写数据则会导致写入线程被阻塞。 并发测试 三个线程并发写入300条数据其中一个线程消费一条。 0 299 最终的队列大小为 299可见线程也是安全的。 由于不管是写入还是获取方法里的操作都需要获取锁才能操作所以整个队列是线程安全的。 ArrayBlockingQueue 下面来看看 JDK 标准的 ArrayBlockingQueue 的实现有了上面的基础会更好理解。 初始化队列 看似要复杂些但其实逐步拆分后也很好理解 第一步其实和我们自己写的一样初始化一个队列大小的数组。 第二步初始化了一个重入锁这里其实就和我们之前使用的 synchronized 作用一致的 只是这里在初始化重入锁的时候默认是非公平锁当然也可以指定为 true 使用公平锁这样就会按照队列的顺序进行写入和消费。 更多关于 ReentrantLock 的使用和原理请参考这里ReentrantLock 实现原理 三四两步则是创建了 notEmpty notFull 这两个条件他的作用于用法和之前使用的 object.wait/notify 类似。 这就是整个初始化的内容其实和我们自己实现的非常类似。 写入队列 其实会发现阻塞写入的原理都是差不多的只是这里使用的是 Lock 来显式获取和释放锁。 同时其中的 notFull.await();notEmpty.signal(); 和我们之前使用的 object.wait/notify 的用法和作用也是一样的。 当然它还是实现了超时阻塞的 API。 也是比较简单使用了一个具有超时时间的等待方法。 消费队列 再看消费队列 也是差不多的一看就懂。 而其中的超时 API 也是使用了 notEmpty.awaitNanos(nanos) 来实现超时返回的就不具体说了。 实际案例 说了这么多来看一个队列的实际案例吧。 背景是这样的 有一个定时任务会按照一定的间隔时间从数据库中读取一批数据需要对这些数据做校验同时调用一个远程接口。 简单的做法就是由这个定时任务的线程去完成读取数据、消息校验、调用接口等整个全流程但这样会有一个问题 假设调用外部接口出现了异常、网络不稳导致耗时增加就会造成整个任务的效率降低因为他都是串行会互相影响。 所以我们改进了方案 其实就是一个典型的生产者消费者模型 生产线程从数据库中读取消息丢到队列里。消费线程从队列里获取数据做业务逻辑。这样两个线程就可以通过这个队列来进行解耦互相不影响同时这个队列也能起到缓冲的作用。 但在使用过程中也有一些小细节值得注意。 因为这个外部接口是支持批量执行的所以在消费线程取出数据后会在内存中做一个累加一旦达到阈值或者是累计了一个时间段便将这批累计的数据处理掉。 但由于开发者的大意在消费的时候使用的是 queue.take() 这个阻塞的 API正常运行没啥问题。 可一旦原始的数据源也就是 DB 中没数据了导致队列里的数据也被消费完后这个消费线程便会被阻塞。 这样上一轮积累在内存中的数据便一直没机会使用直到数据源又有数据了一旦中间间隔较长时便可能会导致严重的业务异常。 所以我们最好是使用 queue.poll(timeout) 这样带超时时间的 api除非业务上有明确的要求需要阻塞。 这个习惯同样适用于其他场景比如调用 http、rpc 接口等都需要设置合理的超时时间。 总结 关于 ArrayBlockingQueue 的相关分享便到此结束接着会继续更新其他并发容器及并发工具。 对本文有任何相关问题都可以留言讨论。 本文涉及到的所有源码 https://github.com/crossoverJie/JCSprout/blob/master/src/main/java/com/crossoverjie/concurrent/ArrayQueue.java 你的点赞与分享是对我最大的支持 转载于:https://www.cnblogs.com/crossoverJie/p/10681080.html
http://www.zqtcl.cn/news/857338/

相关文章:

  • 网站项目策划书模板wordpress修改模版
  • 房地产手机网站模板电脑建立网站
  • 网站自适应手机代码网络服务机构的网站
  • 系统网站重庆智能建站模板
  • wordpress适合优化吗宝塔 wordpress优化
  • 怎么利用网站做外链接怎样做公司网站介绍
  • 广州网站优化渠道木门网站模板
  • 手机网站菜单设计wordpress加联系方式
  • 网站管理助手怎么使用多种郑州网站建设
  • 汉中网站建设费用外贸网站服务商
  • 苏宿工业园区网站建设成功案例色流网站如何做
  • 北沙滩网站建设公司电子商务网站建设管理论文
  • 公司备案证查询网站查询系统网页设计html代码大全及含义
  • 成都开发网站建设做网站一般会出现的问题
  • 企业网站设计布局方式如何在社交网站上做视频推广方案
  • 惠城网站建设服务做1688网站需要懂英语吗
  • 请人做网站要多少钱搜索引擎优化概述
  • 郑州中森网站建设免费网站app生成软件
  • 做诚信通网站seo新手快速入门
  • 做网站怎么去找客户带会员中心WordPress免费主题
  • 网站建设资费安平县护栏网站建设
  • 做视频网站侵权吗个体户网站备案
  • 苏州姑苏区建设局网站智慧团建登录官网手机版
  • 如何搭建一个视频网站广告制作方案
  • 网站策划ps苏州建站公司速找苏州聚尚网络
  • 网站备案 关闭客户制作网站时的问题
  • 项目网站分析推荐做ppt照片的网站
  • wordpress注明网站网站建设需要什么手续
  • 厦门过路费网站福建省建设执业资格注册中心网站
  • c 网站开发案例详解手机网站返回顶部代码