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

【构建并发程序】8-并发队列之阻塞队列

目录

  • 1 BlockingQueue的各个版本
    • 1.1 往队列中添加元素
    • 1.2 往队列中删除元素
  • 2 阻塞队列之“有界”与“无界”
    • 2.1 代码示例

1 BlockingQueue的各个版本

并发队列操作异常版本特殊值版本计时等待版本阻塞版本
出队remove()pool()pool(t:Long,u:TimeUnit)take()
入队add(x:T)offer(x:T)offer(x:T,t:Long,u:TimeUnit)put(x:T)
检查下一个元素elementpeek

1.1 往队列中添加元素

  • add:若队列满了,报异常
  • offer (特殊值版本):若队列满了,还添加报False
  • offer (计时等待版本):若队列满了,则等待如果超出设置的等待时间,还添加报False
  • put:若队列满了,则线程堵塞一直等待空间,以期添加任务元素

1.2 往队列中删除元素

  • remove:若队列为空,报异常
  • pool (特殊值版本):若删除了返回对应的值,如果队列为空删除失败则返回null
  • pool (计时等待版本):若删除了返回对应的值,如果队列为空删除失败 则等待如果超出设置的等待时间 则返回null
  • take:若队列为空,则线程堵塞一直等待空间,以期删除任务元素。

2 阻塞队列之“有界”与“无界”

ArrayBlockingQueue:是一个有界的阻塞队列。
  在创建ArrayBlockingQueue队列时,我们需要设置它的容量,即该队列能够容纳的元素数量的最大值。如果生产者创建元素的速度比消费者处理元素的速度快,那么就应该使用有界队列。否则,不断增长的无界队列会消耗光该程序的所有可用内存。

LinkedBlockingQueue:是一个无界的队列
  如果消费者处理元素的速度要比生产者创建元素的速度快时,就可以使用该无界队列。


2.1 代码示例

  LinkedBlockungQueue无界队列的例子;Main线程中对并发队列进行入队操作,其它线程对并发队列进行出队操作;

class three_并发队列_File(var root: String) {


  // 将队列声明为messages的私有变量
  private val messages = new LinkedBlockingQueue[String]()
  // 一个名为logger的独立守护线程,调用了该队列中的take方法;
  // take是出队的阻塞版本(他会阻止线程logger调用它,知道队列中含有消息为止)

  val logger: Thread = new Thread {
    //setDaemon(true)
    // 将(logger:Thread)设置为守护线程;所有线程都结束后,守护线程就结束(即main线程结束后,所有线程都会结束)
    // 举个例子:
    //  如果我的队列中没有值,也就是我把 ”//fileSystem.logMessage("Testing log!")“注释掉,那么
    // 此时程序就会卡在第一个循环中的 messages.take() {表示的是:若队列为空,则线程堵塞一直等待空间,以期删除任务元素};
    // 但如果我设置成守护线程,则代表者我main线程结束,管你 卡不卡住,此线程都会退出


    // messages.take():并发队列中有值,第一次循环会将其取出来,但由于我只入队了一次值,所以第二次循环时就等待堵塞了;
    override def run(): Unit = {
      while (true) {
        val msg = messages.take()
        //val msg = messages.poll()
        Logger.getRootLogger.info(msg+" -- "+logger.getName)
      }
    }
  }

  logger.start()

  //  入队操作,我们也可以使用add或put方法,因为这个队列是无界的,因此这些方法永远都不会抛出异常
  //或者阻塞调用它们的线程
  def logMessage(msg: String): Boolean = messages.offer(msg)

}

object FileSystemTest extends App {

  val fileSystem = new three_并发队列_File(".")
  fileSystem.logMessage("Testing log!")

  Logger.getRootLogger.info("main 线程结束")

}

相关文章:

  • Mysql之用户管理
  • 内网边界代理
  • 【CSS】笔试题精讲
  • Java并发技术基础
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • python打包exe
  • ros rviz显示orb-slam2保存的轨迹
  • Part 10:Pandas的axis参数【详解】--Pandas和Numpy的结合
  • 【Linux集群教程】02 高可用集群
  • 吴恩达对话刘慈欣:让科幻更有勇气,让人工智能更有想象力
  • RESTFULL请求模式
  • Element---基于VUE的桌面端组件库
  • Java毕设项目——智能仓储系统(java+SSM+Maven+Mysql+Jsp)
  • 构造与方法重载
  • Python小练习一
  • 【翻译】Mashape是如何管理15000个API和微服务的(三)
  • 07.Android之多媒体问题
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • Apache Spark Streaming 使用实例
  • CSS盒模型深入
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • gops —— Go 程序诊断分析工具
  • in typeof instanceof ===这些运算符有什么作用
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • PHP 的 SAPI 是个什么东西
  • ReactNativeweexDeviceOne对比
  • SAP云平台里Global Account和Sub Account的关系
  • TypeScript迭代器
  • Vue.js-Day01
  • 阿里云Kubernetes容器服务上体验Knative
  • 从setTimeout-setInterval看JS线程
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 理清楚Vue的结构
  • 区块链共识机制优缺点对比都是什么
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • [地铁译]使用SSD缓存应用数据——Moneta项目: 低成本优化的下一代EVCache ...
  • zabbix3.2监控linux磁盘IO
  • 阿里云重庆大学大数据训练营落地分享
  • ​油烟净化器电源安全,保障健康餐饮生活
  • #pragma once与条件编译
  • $(selector).each()和$.each()的区别
  • (4)通过调用hadoop的java api实现本地文件上传到hadoop文件系统上
  • (C语言)fread与fwrite详解
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)springboot掌上博客系统 毕业设计063131
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (三)Hyperledger Fabric 1.1安装部署-chaincode测试
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (原創) 如何讓IE7按第二次Ctrl + Tab時,回到原來的索引標籤? (Web) (IE) (OS) (Windows)...
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .CSS-hover 的解释