首页 Java Java面试题 java多线程和并发面试题目(第4题,附答案)

java多线程和并发面试题目(第4题,附答案)

Nov 26, 2019 pm 05:17 PM
java

java多线程和并发面试题目(第4题,附答案)

4、ConcurrentLinkedQueue非阻塞无界链表队列

ConcurrentLinkedQueue是一个线程安全的队列,基于链表结构实现,是一个无界队列,理论上来说队列的长度可以无限扩大。

与其他队列相同,ConcurrentLinkedQueue也采用的是先进先出(FIFO)入队规则,对元素进行排序。   (推荐学习:java面试题目

当我们向队列中添加元素时,新插入的元素会插入到队列的尾部;而当我们获取一个元素时,它会从队列的头部中取出。

因为ConcurrentLinkedQueue是链表结构,所以当入队时,插入的元素依次向后延伸,形成链表;而出队时,则从链表的第一个元素开始获取,依次递增;

值得注意的是,在使用ConcurrentLinkedQueue时,如果涉及到队列是否为空的判断,切记不可使用size()==0的做法,因为在size()方法中,是通过遍历整个链表来实现的,在队列元素很多的时候,size()方法十分消耗性能和时间,只是单纯的判断队列为空使用isEmpty()即可。

public class ConcurrentLinkedQueueTest {<br/>    public static int threadCount = 10;<br/>    public static ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();<br/>    static class Offer implements Runnable {<br/>        public void run() {<br/>            //不建议使用 queue.size()==0,影响效率。可以使用!queue.isEmpty()<br/>            if (queue.size() == 0) {<br/>                String ele = new Random().nextInt(Integer.MAX_VALUE) + "";<br/>                queue.offer(ele);<br/>                System.out.println("入队元素为" + ele);<br/>            }<br/>        }<br/>    }<br/>    static class Poll implements Runnable {<br/>        public void run() {<br/>            if (!queue.isEmpty()) {<br/>                String ele = queue.poll();<br/>                System.out.println("出队元素为" + ele);<br/>            }<br/>        }<br/>    }<br/>    public static void main(String[] agrs) {<br/>        ExecutorService executorService = Executors.newFixedThreadPool(4);<br/>        for (int x = 0; x < threadCount; x++) {<br/>            executorService.submit(new Offer());<br/>            executorService.submit(new Poll());<br/>        }<br/>        executorService.shutdown();<br/>    }<br/>}<br/>

一种输出:

入队元素为313732926<br/>出队元素为313732926<br/>入队元素为812655435<br/>出队元素为812655435<br/>入队元素为1893079357<br/>出队元素为1893079357<br/>入队元素为1137820958<br/>出队元素为1137820958<br/>入队元素为1965962048<br/>出队元素为1965962048<br/>出队元素为685567162<br/>入队元素为685567162<br/>出队元素为1441081163<br/>入队元素为1441081163<br/>出队元素为1627184732<br/>入队元素为1627184732<br/>

ConcurrentLinkedQuere类图

java-63.png

如图ConcurrentLinkedQueue中有两个volatile类型的Node节点分别用来存在列表的首尾节点,其中head节点存放链表第一个item为null的节点,tail则并不是总指向最后一个节点。

Node节点内部则维护一个变量item用来存放节点的值,next用来存放下一个节点,从而链接为一个单向无界列表。

public ConcurrentLinkedQueue(){<br/>    head=tail=new Node<E>(null);<br/>}<br/>

如上代码初始化时候会构建一个 item 为 NULL 的空节点作为链表的首尾节点。

Offer 操作offer 操作是在链表末尾添加一个元素,

下面看看实现原理。

public boolean offer(E e) {<br/>    //e 为 null 则抛出空指针异常<br/>    checkNotNull(e);<br/>    //构造 Node 节点构造函数内部调用 unsafe.putObject,后面统一讲<br/>    final Node<E> newNode = new Node<E>(e);<br/>    //从尾节点插入<br/>    for (Node<E> t = tail, p = t; ; ) {<br/>        Node<E> q = p.next;<br/>        //如果 q=null 说明 p 是尾节点则插入<br/>        if (q == null) {<br/>            //cas 插入(1)<br/>            if (p.casNext(null, newNode)) {<br/>                //cas 成功说明新增节点已经被放入链表,然后设置当前尾节点(包含 head,1,3,5.。。个节点为尾节点)<br/>                if (p != t)// hop two nodes at a time<br/>                    casTail(t, newNode); // Failure is OK. return true;<br/>            }<br/>            // Lost CAS race to another thread; re-read next<br/>        } else if (p == q)//(2)<br/>            //多线程操作时候,由于 poll 时候会把老的 head 变为自引用,然后 head 的 next 变为新 head,所以这里需要<br/>            //重新找新的 head,因为新的 head 后面的节点才是激活的节点<br/>            p = (t != (t = tail)) ? t : head;<br/>        else<br/>            // 寻找尾节点(3)<br/>            p = (p != t && t != (t = tail)) ? t : q;<br/>    }<br/>}<br/>

从构造函数知道一开始有个item为null的哨兵节点,并且head和tail都是指向这个节点。

以上是java多线程和并发面试题目(第4题,附答案)的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

热门话题

Laravel 教程
1604
29
PHP教程
1510
276
如何在Java中实现简单的TCP客户端? 如何在Java中实现简单的TCP客户端? Aug 08, 2025 pm 03:56 PM

Importjava.ioandjava.net.SocketforI/Oandsocketcommunication.2.CreateaSocketobjecttoconnecttotheserverusinghostnameandport.3.UsePrintWritertosenddataviaoutputstreamandBufferedReadertoreadserverresponsesfrominputstream.4.Usetry-with-resourcestoautomati

用Docker将Java应用程序部署到Kubernetes 用Docker将Java应用程序部署到Kubernetes Aug 08, 2025 pm 02:45 PM

容器化Java应用:创建Dockerfile,使用基础镜像如eclipse-temurin:17-jre-alpine,复制JAR文件并定义启动命令,通过dockerbuild构建镜像并用dockerrun测试本地运行。2.推送镜像到容器注册表:使用dockertag标记镜像并推送到DockerHub等注册表,需先登录dockerlogin。3.部署到Kubernetes:编写deployment.yaml定义Deployment,设置副本数、容器镜像和资源限制,编写service.yaml创建

VS代码快捷方式专注于Explorer面板 VS代码快捷方式专注于Explorer面板 Aug 08, 2025 am 04:00 AM

VSCode中可通过快捷键快速切换面板与编辑区。要跳转至左侧资源管理器面板,使用Ctrl Shift E(Windows/Linux)或Cmd Shift E(Mac);返回编辑区可用Ctrl `或Esc或Ctrl 1~9。相比鼠标操作,键盘快捷键更高效且不打断编码节奏。其他技巧包括:Ctrl KCtrl E聚焦搜索框,F2重命名文件,Delete删除文件,Enter打开文件,方向键展开/收起文件夹。

修复:Windows Update无法安装 修复:Windows Update无法安装 Aug 08, 2025 pm 04:16 PM

runthewindowsupdatetrubloubleshooterviaSettings>更新&安全> is esseShootsoAtomationfixCommonissues.2.ResetWindowSupDateComponentsByStoppingRealatedServices,RenamingTheSoftWaredWaredWaredSoftwaredSistribution andCatroot2Folders,intrestrestartingthertingthertingtherserviceSteStoceTocle

如何在Java中使用一个时循环 如何在Java中使用一个时循环 Aug 08, 2025 pm 04:04 PM

AwhileloopinJavarepeatedlyexecutescodeaslongastheconditionistrue;2.Initializeacontrolvariablebeforetheloop;3.Definetheloopconditionusingabooleanexpression;4.Updatethecontrolvariableinsidethelooptopreventinfinitelooping;5.Useexampleslikeprintingnumber

Java对象的序列化过程是什么? Java对象的序列化过程是什么? Aug 08, 2025 pm 04:03 PM

JavaserializationConvertSanObject'SstateIntoAbyTeSteAmForStorageorTransermission,andDeserializationReconstructstheObjectStheObjectFromThstream.1.toenableserialization,aclassMustimustimplementTheSerializableizableface.2.UseObjectObjectObjectObjectOutputputputputputtreamToserialializeanobectizeanobectementeabectenobexpent,savin

什么是Java的哈希图? 什么是Java的哈希图? Aug 11, 2025 pm 07:24 PM

ahashmapinjavaiSadattrastureturethatStoreskey-valuepairsforefficeFitedReval,插入和deletion.itusesthekey’shashcode()methodtodeTermInestorageLageLageAgeLageAgeAgeAgeAgeAneStorageAgeAndAllowSavereo(1)timecomplexityforget()

python numpy阵列示例 python numpy阵列示例 Aug 08, 2025 am 06:13 AM

NumPy数组的使用包括:1.创建数组(如从列表、全零、全一、范围创建);2.形状操作(reshape、转置);3.向量化运算(加减乘除、广播、数学函数);4.索引与切片(一维和二维操作);5.统计计算(最大值、最小值、均值、标准差、求和及轴向操作);这些操作高效且无需循环,适合大规模数值计算,最终掌握需多加练习。

See all articles