首页 文章 精选 留言 我的

精选列表

搜索[java],共10000篇文章
优秀的个人博客,低调大师

突破Java面试(17)-ElasticSearch的部署架构

1 面试题 ES集群部署架构如何 每个索引的数据量大概多少 每个索引大概有多少分片 2 考点分析 问你生产环境咋部署的,说白了,没啥技术含量,就是看你有没有在真正的生产环境里做过ES! 有些同学可能没在生产环境做过,没在线上部署过ES集群,也没实际玩过,也没往ES集群里面导入过几千万甚至是几亿的数据量,可能你就不太清楚这里面的一些生产项目中的细节 如果你是自己就玩过demo,没碰过真实的ES集群,那你可能此时会懵,但是别怕!你一定要云淡风轻的回答,表示你确实干过ES! 3 详解 如果你确实干过ES,那你肯定了解你们生产es集群的实际情况,部署了几台机器?有多少个索引?每个索引有多大数据量?每个索引给了多少个分片?你肯定知道! 但是如果你确实没干过,也别虚,我给你说一个基本的版本,你到时候就简单说一下就好了 ES生产集群我们部署了5台机器,每台机器是6核

优秀的个人博客,低调大师

死磕 java集合之ConcurrentLinkedQueue源码分析

问题 (1)ConcurrentLinkedQueue是阻塞队列吗? (2)ConcurrentLinkedQueue如何保证并发安全? (3)ConcurrentLinkedQueue能用于线程池吗? 简介 ConcurrentLinkedQueue只实现了Queue接口,并没有实现BlockingQueue接口,所以它不是阻塞队列,也不能用于线程池中,但是它是线程安全的,可用于多线程环境中。 那么,它的线程安全又是如何实现的呢?让我们一起来瞧一瞧。 源码分析 主要属性 // 链表头节点 private transient volatile Node<E> head; // 链表尾节点 private transient volatile Node<E> tail; 就这两个主要属性,一个头节点,一个尾节点。 主要内部类 private static class Node<E> { volatile E item; volatile Node<E> next; } 典型的单链表结构,非常纯粹。 主要构造方法 public ConcurrentLinkedQueue() { // 初始化头尾节点 head = tail = new Node<E>(null); } public ConcurrentLinkedQueue(Collection<? extends E> c) { Node<E> h = null, t = null; // 遍历c,并把它元素全部添加到单链表中 for (E e : c) { checkNotNull(e); Node<E> newNode = new Node<E>(e); if (h == null) h = t = newNode; else { t.lazySetNext(newNode); t = newNode; } } if (h == null) h = t = new Node<E>(null); head = h; tail = t; } 这两个构造方法也很简单,可以看到这是一个无界的单链表实现的队列。 入队 因为它不是阻塞队列,所以只有两个入队的方法,add(e)和offer(e)。 因为是无界队列,所以add(e)方法也不用抛出异常了。 public boolean add(E e) { return offer(e); } public boolean offer(E e) { // 不能添加空元素 checkNotNull(e); // 新节点 final Node<E> newNode = new Node<E>(e); // 入队到链表尾 for (Node<E> t = tail, p = t;;) { Node<E> q = p.next; // 如果没有next,说明到链表尾部了,就入队 if (q == null) { // CAS更新p的next为新节点 // 如果成功了,就返回true // 如果不成功就重新取next重新尝试 if (p.casNext(null, newNode)) { // 如果p不等于t,说明有其它线程先一步更新tail // 也就不会走到q==null这个分支了 // p取到的可能是t后面的值 // 把tail原子更新为新节点 if (p != t) // hop two nodes at a time casTail(t, newNode); // Failure is OK. // 返回入队成功 return true; } } else if (p == q) // 如果p的next等于p,说明p已经被删除了(已经出队了) // 重新设置p的值 p = (t != (t = tail)) ? t : head; else // t后面还有值,重新设置p的值 p = (p != t && t != (t = tail)) ? t : q; } } 入队整个流程还是比较清晰的,这里有个前提是出队时会把出队的那个节点的next设置为节点本身。 (1)定位到链表尾部,尝试把新节点放到后面; (2)如果尾部变化了,则重新获取尾部,再重试; 出队 因为它不是阻塞队列,所以只有两个出队的方法,remove()和poll()。 public E remove() { E x = poll(); if (x != null) return x; else throw new NoSuchElementException(); } public E poll() { restartFromHead: for (;;) { // 尝试弹出链表的头节点 for (Node<E> h = head, p = h, q;;) { E item = p.item; // 如果节点的值不为空,并且将其更新为null成功了 if (item != null && p.casItem(item, null)) { // 如果头节点变了,则不会走到这个分支 // 会先走下面的分支拿到新的头节点 // 这时候p就不等于h了,就更新头节点 // 在updateHead()中会把head更新为新节点 // 并让head的next指向其自己 if (p != h) // hop two nodes at a time updateHead(h, ((q = p.next) != null) ? q : p); // 上面的casItem()成功,就可以返回出队的元素了 return item; } // 下面三个分支说明头节点变了 // 且p的item肯定为null else if ((q = p.next) == null) { // 如果p的next为空,说明队列中没有元素了 // 更新h为p,也就是空元素的节点 updateHead(h, p); // 返回null return null; } else if (p == q) // 如果p等于p的next,说明p已经出队了,重试 continue restartFromHead; else // 将p设置为p的next p = q; } } } // 更新头节点的方法 final void updateHead(Node<E> h, Node<E> p) { // 原子更新h为p成功后,延迟更新h的next为它自己 // 这里用延迟更新是安全的,因为head节点已经变了 // 只要入队出队的时候检查head有没有变化就行了,跟它的next关系不大 if (h != p && casHead(h, p)) h.lazySetNext(h); } 出队的整个逻辑也是比较清晰的: (1)定位到头节点,尝试更新其值为null; (2)如果成功了,就成功出队; (3)如果失败或者头节点变化了,就重新寻找头节点,并重试; (4)整个出队过程没有一点阻塞相关的代码,所以出队的时候不会阻塞线程,没找到元素就返回null; 总结 (1)ConcurrentLinkedQueue不是阻塞队列; (2)ConcurrentLinkedQueue不能用在线程池中; (3)ConcurrentLinkedQueue使用(CAS+自旋)更新头尾节点控制出队入队操作; 彩蛋 ConcurrentLinkedQueue与LinkedBlockingQueue对比? (1)两者都是线程安全的队列; (2)两者都可以实现取元素时队列为空直接返回null,后者的poll()方法可以实现此功能; (3)前者全程无锁,后者全部都是使用重入锁控制的; (4)前者效率较高,后者效率较低; (5)前者无法实现如果队列为空等待元素到来的操作; (6)前者是非阻塞队列,后者是阻塞队列; (7)前者无法用在线程池中,后者可以; 欢迎关注我的公众号“彤哥读源码”,查看更多源码系列文章, 与彤哥一起畅游源码的海洋。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册