Java--concurrent并发包下阻塞队列介绍

2023-11-14

JDK提供了7中阻塞队列,这里介绍其中3中,剩余的以此类推原理相同。

1.ArrayBlockingQueue

package com.seeyon.queue;

import java.util.concurrent.ArrayBlockingQueue;

/**
 * Created by yangyu on 16/11/27.
 */

/**
 * ArrayBlockingQueue是数组结构组成的有界阻塞队列
 * 当队列已经满了的时候,put操作会阻塞当前线程,直到队列发生出队操作然后会唤醒put线程在入队
 * 当队列为空的时候,take操作会阻塞当前线程,直到队列发生入队操作后会唤醒take线程进行出队
 */
public class TestArrayBlockingQueue {
    public static void main(String[] args) {
        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue(1);

        try {
            queue.put("1111");
            /**
             * 该操作会被阻塞,知道队列发生出队操作
             */
            queue.put("2222");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

 

2.LinkedBlockingQueue:链表实现的有界阻塞队列

 

3.PriorityBlockingQueue:支持优先级的无界阻塞队列

 

4.DelayQueue

package com.seeyon.queue;

import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

import static java.util.concurrent.TimeUnit.NANOSECONDS;

/**
 * Created by yangyu on 16/11/27.
 */

/**
 * DelayQueue是一个支持延时获取元素的无界队列
 * DelayQueue可以用于如下场景:
 * 1.缓存系统的的设计:用DelayQueue保存缓存元素的有效期,用一个线程循环查询DelayQueue,一旦能从DelayQueue中获取到元素,说明该元素过期了
 * 2.定时任务调度:使用DelayQueue保存当天会执行的任务和执行时间,一旦从DelayQueue中获取到任务就开始执行,TimerQueue就是使用DelayQueue实现的
 * DelayQueue的原理:
 * 1.当线程put元素的时候,DelayQueue会对你put的元素通过其本身的compareTo方法进行排序,延时时间越短的顺序越靠近队列头部
 * 2.当线程take元素的时候,DelayQueue会检测当前是否有Thread已经在等待队头元素了,如果有的话,那么只能阻塞当前前程,等已经取到队头
 * 的Thread完成以后再唤醒。
 * 如果没有Thread在等待队头元素的话,那么会查询一下队头元素还剩多少Delay时间,并且将当前线程设置为队头等待线程,然后让当前线程wait剩余
 * Delay时间后在来获取队头元素。
 */
public class TestDelayQueue {
    public static void main(String[] args) {
        DelayQueue<Message> delayQueue = new DelayQueue<>();
        delayQueue.put(new Message(2000,"yangyu"));

        try {
            System.out.println(delayQueue.take());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("end");
    }

    private static class Message implements Delayed{

        private long nanoTime;

        private String data;

        Message(long millisTime ,String data){
            this.nanoTime = now()+millisTime*(1000*1000);
            this.data = data;
        }

        private final long now(){
            return System.nanoTime();
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(nanoTime - now(), NANOSECONDS);
        }

        @Override
        public int compareTo(Delayed other) {
            if (other == this) // compare zero if same object
                return 0;
            if (other instanceof Message) {
                Message x = (Message) other;
                long diff = nanoTime - x.nanoTime;
                if (diff < 0)
                    return -1;
                else if (diff > 0)
                    return 1;
                else
                    return 1;
            }
            long diff = getDelay(NANOSECONDS) - other.getDelay(NANOSECONDS);
            return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
        }
    }
}

 

5.SynchronousQueue

import java.util.concurrent.SynchronousQueue;

/**
 * Created by yangyu on 16/11/27.
 */

/**
 * SynchronousQueue是一个不存储数据的队列,只是做数据的的传递工作
 * 同步队列,一个put操作必须等待一个take操作,否则线程被阻塞
 * 同样,一个take操作必须等待一个put操作,否则线程被阻塞
 * 
 * Executors中newCachedThreadPool()(可缓存线程池),就是使用的SynchronousQueue
 * 当一个任务被放入可缓存线程池以后,会调用SynchronousQueue的offer方法来判断是否有正在等待取任务的线程
 * offer方法:如果有线程正在等待取任务则将任务交给该线程并且返回true,如果没有线程等待取任务则返回false
 * 如果没有正在等待的线程,那么可缓存线程池会重新启动一个线程来执行这个任务
 * 当该线程执行完任务以后,会去SynchronousQueue队列中获取数据,等待60s,直到60s还未获取到任务则就自行关闭了
 */
public class TestSynchronousQueue {
    public static void main(String[] args) {
        SynchronousQueue<String> strings = new SynchronousQueue<>();
        Thread t =new Thread(()->{
            try {
                /**
                 * 该take操作会被阻塞,直到后面的strings.put("yangyu")操作后,当前线程才会被唤醒
                 */
                System.out.println(strings.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t.start();

        
        try {
            Thread.sleep(2000);
            /**
             * 唤醒阻塞线程并且传递数据
             */
            strings.put("yangyu");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("完成");

    }
}

 

6.LinkedTransferQueue

 

7.LinkedBlockingDeqeue:是一个链表结构组成的双向阻塞队列,可以从队列的两端插入或者移出元素。

转载于:https://www.cnblogs.com/eoss/p/6106312.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java--concurrent并发包下阻塞队列介绍 的相关文章

随机推荐

  • 如何使用万用表测量二极管的阻值

    如何使用万用表测量二极管的阻值 1 测量时 选用万用表的 欧姆 挡 一般用R x100或R xlk挡 而不用Rx1或R x10k挡 因为Rxl挡的电流太大 容易烧坏二极管 R xlok挡的内电源电压太大 易击穿二极管 2 将两表棒分别接在二
  • 在MacOS下使用Fiddler抓包

    在MacOS下使用Fiddler抓包 在MacOS下使用Fiddler抓包 有两种方式 分别是安装Mac版的Fiddler 或者是用虚拟机 安装Windows系统 在Windows系统下运行Fiddler对Mac系统中的内容进行抓包 Mac
  • AES128加密算法的实现(C/Java/C#)

    最近项目中有一个需求 实现AES128的加密算法 用于硬件和平台的通信 硬件加密部分使用C语言完成 平台有两种不同的环境 java Linux 和C Windows 在网上搜集了一些资料 有人实现过纯C代码的AES加密解密算法 这样实际上有
  • Java 新特性 UpdateWrapper-(修改指定字段)

    UpdateWrapper的使用 UpdateWrapper的使用 修改指定id的名字 可在后增加条件 常用的连接条件 UpdateWrapper的使用 QueryWrapperLambdaQueryWrapper 条件查询 修改指定id的
  • 在 WebStorm 中开发 uni-app

    代码已上传至github github代码地址 https github com Miofly mio git CLI 工程 全局安装 vue cli 3 x 如已安装请跳过此步骤 npm install g vue cli 通过 CLI
  • JavaScript 常见鼠标事件

    常见鼠标事件类型1 1 click鼠标左键点击 2 mousedown 鼠标按下时触发 3 mouseup 鼠标弹起时触发 4 mousemove move移动 鼠标在固定的位置一移动就触发移动 就触发 5 mouseenter 鼠标移入触
  • Qt 识别 DM 码

    Qt 识别 DM 码 下载libdmtx 添加源码到Qt 工程 生成一维码 二维码 识别普通二维码网上库很多 这个库专门识别 DM码 下载libdmtx https github com dmtx libdmtx 添加源码到Qt 工程 li
  • 前程无忧guid、acw_sc__v2

    文章目录 声明 目标网站 acw sc v2分析 python调用测试 话外拓展 风控浅析 往期逆向文章推荐 声明 本文章中所有内容仅供学习交流 严禁用于商业用途和非法用途 否则由此产生的一切后果均与作者无关 若有侵权 请私信我立即删除 目
  • 新型智能优化算法——海鸥优化算法(基于Matlab代码实现)

    目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 1 概述 2019 年 Dhiman G等人提出了一种受自然界海鸥启发的新颖全局优化算法 海鸥优化算法 Seagull Optimization Algorithm SOA
  • 攻防世界RE练习

    攻防世界 一开始学习下re 产生了兴趣 game 这个题目在某个CTF平台做过了0 0 再做一遍 跟着WP 0 0 首先用ExeinfoPe或者Peid查壳 也可以使用file命令查看相关信息 32位程序 使用ida打开 F5反编译 程序逻
  • Blender基础操作:面操作细分、整体切分、挤出、内插、尖分、融并、切割、面的法向、填充等

    目录 1 面操作 进入 面选择 模式 选择一个面 2 面的挤出 3 内插面 4 尖分面 5 面的切割 6 面的法向normal 7 填充面 8 X Ray透视 1 面操作 进入 面选择 模式 选择一个面 4种操作手段 菜单 工具 右键菜单
  • WireShark_过滤语法

    WireShark 过滤语法 过滤IP 如来源IP或者目标IP等于某个IP 例子 ip src eq 192 168 1 107 or ip dst eq 192 168 1 107 或者 ip addr eq 192 168 1 107
  • python网络爬虫--selenium(6)--练习

    一 打开网页获取页面源码 from selenium webdriver chrome import webdriver 初始化 需要加载浏览器驱动 driver webdriver WebDriver executable path ch
  • 为解决cpu与主存的速度匹配可采用什么

    为解决cpu与主存的速度匹配可采用cache存储器 cache存储器是位于cpu和主存储器DRAM之间 规模较小 但速度很高的存储器 通常由静态存储器组成 静态存储器是位于cpu与内存间的一种容量较小但速度很高的存储器 为解决CPU和主存的
  • 计算机中丢失msvcp120.dll是什么意思,电脑提示msvcp120.dll丢失怎么办

    一些朋友在使用电脑的过程中 可能会遇到 msvcp120 dll丢失 的情况 那电脑提示msvcp120 dll丢失怎么办呢 碰到了这种情况不用慌 下面和大家分享电脑提示msvcp120 dll丢失解决方法 电脑提示msvcp120 dll
  • 完整教程:设计一款小巧但强大的传感器

    由IEEE制定的新型单对以太网 SPE 或10BASE T1L物理层标准 为传输设备运行状况信息实施状态监测 CbM 应用提供了新的连接解决方案 SPE提供共享电源和高带宽数据架构 可通过低成本双线电缆在超过1000米的距离实现10 Mbp
  • 实时汇率获取 解决跨域以及循环Ajax请求

    前端框架 ExtJs 币种代码 var currencys curCode USD curCode CNY curCode HKD setInterval function for var idx 0 len currencys lengt
  • Java 单链表

    package com abin lee tree test import com abin des algorithm common json jackson JsonUtil import java util concurrent at
  • vue动态表单封装

    需求 根据传参动态生成表单 例如搜索表格的表单 1 组件封装
  • Java--concurrent并发包下阻塞队列介绍

    JDK提供了7中阻塞队列 这里介绍其中3中 剩余的以此类推原理相同 1 ArrayBlockingQueue package com seeyon queue import java util concurrent ArrayBlockin