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

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 线程结束")

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值