美文网首页
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