亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java并發(fā)編程之阻塞隊(duì)列詳解

 更新時(shí)間:2016年03月21日 17:17:12   作者:溫布利往事  
這篇文章主要為大家詳細(xì)介紹了Java并發(fā)編程之阻塞隊(duì)列,什么是阻塞隊(duì)列?主要的阻塞隊(duì)列及其方法介紹,感興趣的小伙伴們可以參考一下

1、什么是阻塞隊(duì)列?
  隊(duì)列是一種數(shù)據(jù)結(jié)構(gòu),它有兩個(gè)基本操作:在隊(duì)列尾部加入一個(gè)元素,從隊(duì)列頭部移除一個(gè)元素。阻塞隊(duì)里與普通的隊(duì)列的區(qū)別在于,普通隊(duì)列不會(huì)對(duì)當(dāng)前線(xiàn)程產(chǎn)生阻塞,在面對(duì)類(lèi)似消費(fèi)者-生產(chǎn)者模型時(shí),就必須額外的實(shí)現(xiàn)同步策略以及線(xiàn)程間喚醒策略。使用阻塞隊(duì)列,就會(huì)對(duì)當(dāng)前線(xiàn)程產(chǎn)生阻塞,當(dāng)隊(duì)列是空時(shí),從隊(duì)列中獲取元素的操作將會(huì)被阻塞,當(dāng)隊(duì)列是滿(mǎn)時(shí),往隊(duì)列里添加元素的操作也會(huì)被阻塞。


2、主要的阻塞隊(duì)列及其方法

java.util.concurrent包下提供主要的幾種阻塞隊(duì)列,主要有以下幾個(gè):

1)ArrayBlockingQueue:基于數(shù)組實(shí)現(xiàn)的阻塞隊(duì)列,在創(chuàng)建ArrayBlockingQueue對(duì)象時(shí)必須指定其容量大小,還可以指定訪問(wèn)策略,默認(rèn)情況下為非公平的,即不保證等待時(shí)間最長(zhǎng)的線(xiàn)程最優(yōu)先能夠訪問(wèn)隊(duì)列。
2)、LinkedBlockingQueue:基于鏈表實(shí)現(xiàn)的一個(gè)阻塞隊(duì)列,在創(chuàng)建LinkedBlockingQueue對(duì)象時(shí)如果不指定容量大小,則默認(rèn)大小為Integer.MAX_VALUE。
3)、以上2種隊(duì)列都是先進(jìn)先出隊(duì)列,而PriorityBlockingQueue卻不是,它會(huì)按照元素的優(yōu)先級(jí)對(duì)元素進(jìn)行排序,按照優(yōu)先級(jí)順序出隊(duì),每次出隊(duì)的元素都是優(yōu)先級(jí)最高的元素。注意,此阻塞隊(duì)列為無(wú)界阻塞隊(duì)列,即容量沒(méi)有上限(通過(guò)源碼就可以知道,它沒(méi)有容器滿(mǎn)的信號(hào)標(biāo)志),前面2種都是有界隊(duì)列。
4)、DelayQueue:基于PriorityQueue,一種延時(shí)阻塞隊(duì)列,DelayQueue中的元素只有當(dāng)其指定的延遲時(shí)間到了,才能夠從隊(duì)列中獲取到該元素。DelayQueue也是一個(gè)無(wú)界隊(duì)列,因此往隊(duì)列中插入數(shù)據(jù)的操作(生產(chǎn)者)永遠(yuǎn)不會(huì)被阻塞,而只有獲取數(shù)據(jù)的操作(消費(fèi)者)才會(huì)被阻塞。

阻塞隊(duì)列包括了非阻塞隊(duì)列中的大部分方法,還提供另外若干非常有用的方法:

put方法用來(lái)向隊(duì)尾存入元素,如果隊(duì)列滿(mǎn),則等待;
take方法用來(lái)從隊(duì)首取元素,如果隊(duì)列為空,則等待;
offer方法用來(lái)向隊(duì)尾存入元素,如果隊(duì)列滿(mǎn),則等待一定的時(shí)間,當(dāng)時(shí)間期限達(dá)到時(shí),如果還沒(méi)有插入成功,則返回false;否則返回true;
poll方法用來(lái)從隊(duì)首取元素,如果隊(duì)列空,則等待一定的時(shí)間,當(dāng)時(shí)間期限達(dá)到時(shí),如果取到,則返回null;否則返回取得的元素;

下面看一段代碼:

import java.util.concurrent.ArrayBlockingQueue;

/** 
 * @author 作者:徐劍  E-mail:anxu_2013@163.com 
 * @version 創(chuàng)建時(shí)間:2016年3月20日 下午12:52:53 
 * 類(lèi)說(shuō)明 
 */
public class BlockingQueue
{
  public static void main(String[] args) throws InterruptedException
  {
    java.util.concurrent.BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(5);
    for (int i = 0; i < 10; i++)
    {
      // 將指定元素添加到此隊(duì)列中
      blockingQueue.put("加入元素" + i);
      System.out.println("向阻塞隊(duì)列中添加了元素:" + i);
    }
    System.out.println("程序到此運(yùn)行結(jié)束,即將退出----");
  }
}

  當(dāng)限制阻塞隊(duì)列數(shù)量為5時(shí),添加了5個(gè)元素之后,繼續(xù)添加將會(huì)隊(duì)列外阻塞等待,此時(shí)程序并未終止。

  

  當(dāng)隊(duì)列滿(mǎn)了之后,我們將隊(duì)首元素移除,則可以繼續(xù)向阻塞隊(duì)列中添加元素,代碼如下:

public class BlockingQueue
{
  public static void main(String[] args) throws InterruptedException
  {
    java.util.concurrent.BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(5);
    for (int i = 0; i < 10; i++)
    {
      // 將指定元素添加到此隊(duì)列中
      blockingQueue.put("加入元素" + i);
      System.out.println("向阻塞隊(duì)列中添加了元素:" + i);
      if(i>=4)
        System.out.println("移除隊(duì)首元素"+blockingQueue.take());
    }
    System.out.println("程序到此運(yùn)行結(jié)束,即將退出----");
  }

  執(zhí)行結(jié)果如下:

  

3、阻塞隊(duì)列的實(shí)現(xiàn)原理
  下面主要看一下ArrayBlockingQueue的實(shí)現(xiàn)原理。

  首先看一下ArrayBlockingQueue類(lèi)的成員變量:

public class ArrayBlockingQueue<E> extends AbstractQueue<E>
    implements BlockingQueue<E>, java.io.Serializable {

  /** 底層存儲(chǔ)結(jié)構(gòu)-數(shù)組 */
  final Object[] items;

  /** 隊(duì)首元素下標(biāo) */
  int takeIndex;

  /** 隊(duì)尾元素下標(biāo) */
  int putIndex;

  /**隊(duì)列元素總數(shù) */
  int count;

  /** 重入鎖 */
  final ReentrantLock lock;

  /** notEmpty等待條件 */
  private final Condition notEmpty;
  /** notFull等待條件 */
  private final Condition notFull;
  /**
   * Shared state for currently active iterators, or null if there
   * are known not to be any. Allows queue operations to update
   * iterator state.
   */
  transient Itrs itrs = null;

可以看到,ArrayBlockingQueue用來(lái)存儲(chǔ)元素的實(shí)際上是一個(gè)數(shù)組。

再看下ArrayBlockingQueue兩個(gè)重要方法的實(shí)現(xiàn),put()和take():

public void put(E e) throws InterruptedException
  {
    //先檢查e是否為空
    checkNotNull(e);
    //獲取鎖
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try
    {
      //當(dāng)隊(duì)列已滿(mǎn),進(jìn)入條件等待
      while (count == items.length)
        notFull.await();
      //隊(duì)列不滿(mǎn),進(jìn)行入隊(duì)列操作
      enqueue(e);
    } 
    finally
    {
      //釋放鎖
      lock.unlock();
    }
  }

再看下具體的入隊(duì)操作:

private void enqueue(E x)
  {
    final Object[] items = this.items;
    //隊(duì)尾入隊(duì)
    items[putIndex] = x;
    if (++putIndex == items.length)
      putIndex = 0;
    //隊(duì)列總數(shù)+1
    count++;
    //notempty條件的等待集中隨機(jī)選擇一個(gè)線(xiàn)程,解除其阻塞狀態(tài)
    notEmpty.signal();
  }

下面是take()方法的源代碼:

public E take() throws InterruptedException
  {
    //獲取鎖
    final ReentrantLock lock = this.lock;
    lock.lockInterruptibly();
    try
    {
      //隊(duì)列為空
      while (count == 0)
        //線(xiàn)程加入notEmpty條件等待集
        notEmpty.await();
      //非空,出隊(duì)列
      return dequeue();
    } finally
    {
      //釋放鎖
      lock.unlock();
    }
  }

4、阻塞隊(duì)列的應(yīng)用:實(shí)現(xiàn)消費(fèi)者-生產(chǎn)者模式

/** 
 * @author 作者:徐劍  E-mail:anxu_2013@163.com 
 * @version 創(chuàng)建時(shí)間:2016年3月20日 下午2:21:55 
 * 類(lèi)說(shuō)明:阻塞隊(duì)列實(shí)現(xiàn)的消費(fèi)者-生產(chǎn)者模式
 */
public class Test
{
  private int queueSize = 10;
  private ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(queueSize);
  public static void main(String[] args)
  {
    Test test = new Test();
    Producer producer = test.new Producer();
    Consumer consumer = test.new Consumer();
    producer.start();
    consumer.start();
  }
  class Consumer extends Thread
  {
    @Override
    public void run()
    {
      consume();
    }

    private void consume()
    {
      while (true)
      {
        try
        {
          queue.take();
          System.out.println("從隊(duì)列取走一個(gè)元素,隊(duì)列剩余" + queue.size() + "個(gè)元素");
        } catch (InterruptedException e)
        {
          e.printStackTrace();
        }
      }
    }
  }
  class Producer extends Thread
  {
    @Override
    public void run()
    {
      produce();
    }
    private void produce()
    {
      while (true)
      {
        try
        {
          queue.put(1);
          System.out.println("向隊(duì)列取中插入一個(gè)元素,隊(duì)列剩余空間:"+ (queueSize - queue.size()));
        } catch (InterruptedException e)
        {
          e.printStackTrace();
        }
      }
    }
  }
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助。

相關(guān)文章

  • Java實(shí)現(xiàn)視頻自定義裁剪功能

    Java實(shí)現(xiàn)視頻自定義裁剪功能

    這篇文章主要介紹了如何通過(guò)java實(shí)現(xiàn)視頻裁剪,可以將視頻按照自定義尺寸進(jìn)行裁剪,文中的示例代碼簡(jiǎn)潔易懂,感興趣的可以了解一下
    2022-01-01
  • SpringBoot2 整合Ehcache組件,輕量級(jí)緩存管理的原理解析

    SpringBoot2 整合Ehcache組件,輕量級(jí)緩存管理的原理解析

    這篇文章主要介紹了SpringBoot2 整合Ehcache組件,輕量級(jí)緩存管理,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Spring Boot攔截器Interceptor與過(guò)濾器Filter深度解析(區(qū)別、實(shí)現(xiàn)與實(shí)戰(zhàn)指南)

    Spring Boot攔截器Interceptor與過(guò)濾器Filter深度解析(區(qū)別、實(shí)現(xiàn)與實(shí)戰(zhàn)指南)

    對(duì)比SpringBoot攔截器與過(guò)濾器在執(zhí)行順序、作用范圍、異常處理等核心差異,指導(dǎo)開(kāi)發(fā)實(shí)踐與選型策略,強(qiáng)調(diào)攔截器適合Web層通用邏輯,過(guò)濾器用于底層處理,建議結(jié)合APM工具優(yōu)化性能,感興趣的朋友跟隨小編一起看看吧
    2025-06-06
  • java7鉆石語(yǔ)法知識(shí)點(diǎn)總結(jié)

    java7鉆石語(yǔ)法知識(shí)點(diǎn)總結(jié)

    在本篇文章里小編給大家整理的是關(guān)于java7鉆石語(yǔ)法的相關(guān)知識(shí)點(diǎn)內(nèi)容,有需要的朋友們參考下。
    2019-11-11
  • Java中@RequiredArgsConstructor使用詳解

    Java中@RequiredArgsConstructor使用詳解

    這篇文章主要介紹了Java中@RequiredArgsConstructor使用的相關(guān)資料,@RequiredArgsConstructor是Lombok庫(kù)提供的一個(gè)注解,用于自動(dòng)生成一個(gè)包含所有final字段和非空字段的構(gòu)造函數(shù),需要的朋友可以參考下
    2025-05-05
  • Java手動(dòng)配置線(xiàn)程池過(guò)程詳解

    Java手動(dòng)配置線(xiàn)程池過(guò)程詳解

    這篇文章主要介紹了Java手動(dòng)配置線(xiàn)程池過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • java中@NotBlank限制屬性不能為空

    java中@NotBlank限制屬性不能為空

    在實(shí)體類(lèi)的對(duì)應(yīng)屬性上添 @NotBlank注解,可以實(shí)現(xiàn)對(duì)空置的限制,本文就來(lái)介紹一下java中@NotBlank限制屬性不能為空,感興趣的可以了解一下
    2024-01-01
  • Java正則表達(dá)式(匹配、切割、替換、獲取)等方法

    Java正則表達(dá)式(匹配、切割、替換、獲取)等方法

    這篇文章主要介紹了Java正則表達(dá)式(匹配、切割、替換、獲取)等方法的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • 超詳細(xì)講解Java異常

    超詳細(xì)講解Java異常

    Java 異常機(jī)制可以使程序中異常處理代碼和正常業(yè)務(wù)代碼分離,保證程序代碼更加優(yōu)雅,并提高程序健壯性。本文超詳細(xì)講解了Java異常,感興趣的小伙伴可以參考一下這篇文章
    2021-09-09
  • java?AES加密/解密實(shí)現(xiàn)完整代碼(附帶源碼)

    java?AES加密/解密實(shí)現(xiàn)完整代碼(附帶源碼)

    這篇文章主要介紹了java?AES加密/解密實(shí)現(xiàn)的相關(guān)資料,包括AES加密算法的基本原理、Java加密API的使用方法以及項(xiàng)目實(shí)現(xiàn)的步驟和代碼示例,需要的朋友可以參考下
    2025-04-04

最新評(píng)論