美文网首页
5、阻塞队列(BlockingQueue)和同步队列(Synch

5、阻塞队列(BlockingQueue)和同步队列(Synch

作者: i小雨 | 来源:发表于2020-11-19 09:59 被阅读0次

队列:FIFO(先进先出)
阻塞:

  • 写入:如果队列满了,就必须阻塞等待
  • 读取:如果队列为空,必须阻塞等待生产。


    1605668690(1).jpg
    图片.png
    图片.png

ArrayBlockingQueue的四种API

示例1:(会抛出异常)

 /**
  *会抛出异常
  */
 public static void test1(){
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);

        System.out.println(blockingQueue.add("a"));
        System.out.println(blockingQueue.add("b"));
        System.out.println(blockingQueue.add("c"));
        //System.out.println(blockingQueue.add("d"));  //报异常:IllegalStateException: Queue full

        System.out.println(blockingQueue.element());  //查看队首元素

        System.out.println("============================");

        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        //System.out.println(blockingQueue.remove());  //报异常:NoSuchElementException
    }

示例2:(有返回值,不会抛出异常)

 public static void test2(){
        //队列大小
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);

        System.out.println(blockingQueue.offer("a"));
        System.out.println(blockingQueue.offer("b"));
        System.out.println(blockingQueue.offer("c"));
        System.out.println(blockingQueue.offer("d")); //false   不抛出异常

        System.out.println(blockingQueue.peek()); //查看队首元素

        System.out.println("============================");

        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());  //null
    }

返回值:

true
true
true
false
============================
a
b
c
null

示例3:等待,阻塞(一直阻塞)

 public static void test3() throws InterruptedException {
        //队列大小
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);

        blockingQueue.put("a");
        blockingQueue.put("b");
        blockingQueue.put("c");
        //blockingQueue.put("d"); //队列没有位置了,会一直阻塞

        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());  //没有元素了,也会一直等待(阻塞)

    }

示例3:等待,阻塞(等待超时)

public static void test4() throws InterruptedException {
        //队列大小
        ArrayBlockingQueue blockingQueue = new ArrayBlockingQueue<>(3);

        System.out.println(blockingQueue.offer("a"));
        System.out.println(blockingQueue.offer("b"));
        System.out.println(blockingQueue.offer("c"));
        System.out.println(blockingQueue.offer("d",2, TimeUnit.SECONDS));  //等待超过2秒钟就退出

        System.out.println("==============================");

        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll(2,TimeUnit.SECONDS));//等待超过2秒钟就退出
    }
图片.png

SynchronousQueue 同步队列

没有容量,进去一个元素必须等待取出来后才能往里面放一个元素。(put、take)

package com.company.blockingqueue;

import java.util.concurrent.BlockingDeque;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

/**
 *同步队列
 */
public class TestSynchronizedQueue {

    public static void main(String[] args) {
        SynchronousQueue<String> synchronousQueue = new SynchronousQueue<>();

        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName()+" put 1");
                synchronousQueue.put("1");
                System.out.println(Thread.currentThread().getName()+" put 2");
                synchronousQueue.put("2");
                System.out.println(Thread.currentThread().getName()+" put 3");
                synchronousQueue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"T1").start();

        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+" take "+synchronousQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+" take "+synchronousQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+" take "+synchronousQueue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"T2").start();
    }

}

结果:

T1 put 1
T2 take 1
T1 put 2
T2 take 2
T1 put 3
T2 take 3

相关文章

网友评论

      本文标题:5、阻塞队列(BlockingQueue)和同步队列(Synch

      本文链接:https://www.haomeiwen.com/subject/bioqiktx.html