阻塞佇列——四組API

沒有你哪有我發表於2021-02-28
方式 丟擲異常 有返回值,不丟擲異常 阻塞等待 超時等待
新增 add() offer() put() offer(...)
移除 remove() poll() take() poll(...)
檢測隊首元素 element() peek()

第一組

1、新增丟擲異常
public class Demo01 {
    public static void main(String[] args) {
        // 構造方法引數:public ArrayBlockingQueue(int capacity, boolean fair)
        // 第一個引數:初始化阻塞佇列的容量大小
        // 第二個引數:指定該阻塞佇列是否為公平或不公平鎖

        BlockingQueue<String> queue = new ArrayBlockingQueue<>(2);

        // 新增元素
        queue.add("a");
        queue.add("b");
        queue.add("c");
    }
}

執行結果:

2、移除丟擲異常

public class Demo01 {
    public static void main(String[] args) {
        // 構造方法引數:public ArrayBlockingQueue(int capacity, boolean fair)
        // 第一個引數:初始化阻塞佇列的容量大小
        // 第二個引數:指定該阻塞佇列是否為公平或不公平鎖

        BlockingQueue<String> queue = new ArrayBlockingQueue<>(2);

        // 新增元素
        System.out.println(queue.add("a"));
        System.out.println(queue.add("b"));

        // 移除元素
        queue.remove();
        queue.remove();
        queue.remove();
    }
}

執行結果:

第二組

1、新增有返回值

package com.lzp.blockqueue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * @Author LZP
 * @Date 2020/8/8 8:12
 * @Version 1.0
 *
 * 有返回值,且不丟擲異常
 */
public class Demo02 {
    public static void main(String[] args) {
        // 建立阻塞佇列物件
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);

        // 新增元素:若新增成功,則返回true,反之,則返回false
        System.out.println(queue.offer(1));
        System.out.println(queue.offer(2));
        System.out.println(queue.offer(3));
        System.out.println(queue.offer(4));
    }
}

執行結果:

2、移除有返回值

package com.lzp.blockqueue;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * @Author LZP
 * @Date 2020/8/8 8:12
 * @Version 1.0
 *
 * 有返回值,且不丟擲異常
 */
public class Demo02 {
    public static void main(String[] args) {
        // 建立阻塞佇列物件
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(3);

        // 新增元素:若新增成功,則返回true,反之,則返回false
        System.out.println(queue.offer(1));
        System.out.println(queue.offer(2));
        System.out.println(queue.offer(3));
        System.out.println(queue.offer(4));

        // 移除元素:若移除成功,則返回移除的值,反之,則返回false
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
    }
}

執行結果:

第三組

1、新增時,如果佇列已滿,則阻塞等待

package com.lzp.blockqueue;

import java.util.Iterator;
import java.util.concurrent.*;

/**
 * @Author LZP
 * @Date 2020/8/8 8:28
 * @Version 1.0
 *
 * 阻塞等待,即一直等待,直到可以往佇列裡新增或移除元素為止
 *
 * 注意:普通佇列只能從隊首取第一個元素
 * 新增阻塞
 */
public class Demo03 {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(4);

        // 開啟一個執行緒先把佇列裡添滿元素
        new Thread(() -> {
            System.out.println("-----" + Thread.currentThread().getName() + "正在往阻塞佇列裡新增元素------");
            try {
                for (int i = 1; i <= 4; i++) {
                    TimeUnit.SECONDS.sleep(1);
                    queue.put(i + "");
                    // element()方法,用來取佇列的隊首元素
                    System.out.println("-----成功新增第" + i + "個元素-----" + i);
                }
                System.out.println("-----" + Thread.currentThread().getName() + "新增元素完畢------");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        // 判斷當前執行緒數,如果>2則一直等待,不能往下執行
        // 為了保證能將佇列添滿元素,再進行後續操作
        while ((Thread.activeCount() > 2)) {
        }

//        System.out.println("遍歷開始");
//        Iterator<String> iterator = queue.iterator();
//        while (iterator.hasNext()) {
//            System.out.println(iterator.next());
//        }
//        System.out.println("遍歷結束");

        // 此時開啟一個執行緒去往佇列裡新增元素
        new Thread(() -> {
            try {
                System.out.println("-----" + Thread.currentThread().getName() + "開始新增元素------");
                String str = "李時珍的皮";
                queue.put(str);
                System.out.println("-----" + Thread.currentThread().getName() + "成功新增元素------" + str);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        TimeUnit.SECONDS.sleep(3);

//        // 移除元素
//        System.out.println(queue.take());

        // 讓主執行緒等了3秒之後,然後派一個執行緒去移除元素

        new Thread(() -> {
            try {
                System.out.println("-----" + Thread.currentThread().getName() + "開始移除元素------");
                String str = queue.take();
                System.out.println(str);
                System.out.println("-----" + Thread.currentThread().getName() + "成功移除元素------" + str);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

執行結果:

相關文章