美文网首页
并发编程_Collections&&Queue体系分析

并发编程_Collections&&Queue体系分析

作者: 桑翔 | 来源:发表于2020-07-02 01:08 被阅读0次

    日期:2020/7/1   桑翔

                            BlockingQueue阻塞队列

        1.通常用数组和链表实现

        2.一般而言队列具备FIFO先进先出的特性,当然也有双端队列(Deque)优先级队列 

            主要操作:入队(EnQueue)与出队(Dequeue)

    一.ArrayBlockingQueue 

    1.定义:由数组支持的有界队列 ,容量大小在创建ArrayBlockingQueue对象时已定义好

    //定义队列

    BlockingQueue<Ball> blockingQueue = new ArrayBlockingQueue<Ball>(1);

    //向队列中放入对象

    blockingQueue.put(ball);

    //从队列中拿出对象

    blockingQueue.take();


    1.源码分析

          1.1  new ArrayBlockingQueue(1)

        非公平锁有自己同步队列CLH,用来记录等待获取独占锁的线程

        创建的两组条件分别对应ArrayBlockingQueue的take(取),put(存)两种操作,用来判断队列是否已经满了或者是否为空---------->其实就是创建了2个条件队列,这样就存在了3个队列

        1.2  blockingQueue.put(ball);

             1.2.1   put操作

                1.先要获取 独占锁    

                2.判断当前队列是否已满(因为该队列是阻塞有界队列)

                3.notFull.wait();调用

                            将线程放入条件队列中排队

                            释放独占锁

                            判断是否在同步队列中,不在则阻塞线程

            1.2.2  notFull.wait()操作

    public final void await()throws InterruptedException {

    //如果当前线程被中断则直接抛出异常

        if (Thread.interrupted())

    throw new InterruptedException();

    //把当前节点加入条件队列(请看下一张代码截图 [1.0])

        Node node = addConditionWaiter();

    //释放掉已经获取的独占锁资源,并返回释放锁的次数(这里是释放掉所有的锁),因为在put之前是进行过加锁操作的

        int savedState = fullyRelease(node);(请看下一张代码截图 [2.0])

    int interruptMode =0;

    //判断此线程节点在不在同步队列中,如果不在同步队列中则不断挂起

      (请看下一张代码截图 [3.0]))

        while (!isOnSyncQueue(node)) {

    //已经释放了锁,并且已经存在在条件队列中,阻塞线程,跳出while循环

    LockSupport.park(this);

    //判断此节点是中断的还是可以被正常唤醒的

     //1.如果现在不是中断的,即正常被signal唤醒则返回0,   2.如果节点由中断加入同步队列则返回THROW_IE,由signal加入同步队列则返回REINTERRUPT

    //会将条件队列中的这个节点转运到同步队列中,因为只有同步队列中的线程才会被唤醒

    (请看下一张代码截图 [4.0]

            if ((interruptMode = checkInterruptWhileWaiting(node)) !=0)

    break;

    }

    /**

    * 走到这里说明节点已经条件满足被加入到了同步队列中或者中断了

    * 在处理中断之前首先要做的是从同步队列中成功获取锁资源

    */

        if (acquireQueued(node, savedState) && interruptMode !=THROW_IE)

    interruptMode =REINTERRUPT;

    //走到这里说明已经成功获取到了独占锁,接下来就做些收尾工作

    //删除条件队列中被取消的节点

        if (node.nextWaiter !=null)// clean up if cancelled

            unlinkCancelledWaiters();

    //根据不同模式处理中断

        if (interruptMode !=0)

    reportInterruptAfterWait(interruptMode);

    }

    1.0

                创捷节点以后,释放锁

    2.0 3.0 4.0

    相关文章

      网友评论

          本文标题:并发编程_Collections&&Queue体系分析

          本文链接:https://www.haomeiwen.com/subject/dfdkqktx.html