java多线程阻塞队列分析(BlockingQueue)及SynchronousQueue:同步队列

说到队列:它是链表结构
什么时候会阻塞队列呢?如下图所示
在这里插入图片描述
阻塞:队列
在这里插入图片描述首先我们看看阻塞队列类中的结构:
在这里插入图片描述由上图可知阻塞队列和set list同等地位,故也十分重要
所以说BlockingQueue不是新的东西
问:什么时候我们会使用阻塞队列?
答:多线程,线程池多线程并发处理,线程池
Blockingdeque:双端队列:两头都可操作,能返回值
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
学会使用队列:

添加,移除
四组API

方式 抛出异常 不会抛出异常,有返回值 阻塞等待 超时等待
添加 add() offer() put() offer(“d”, 2, TimeUnit.SECONDS)
移除 remove() poll() take() poll(2,TimeUnit.SECONDS)
检测队列首 element() peek()
System.out.println(blockingQueue.element());//返回队首元素
 System.out.println(blockingQueue.peek());//检测队首元素

1.代码抛出异常

package com.Blockqueue;

import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ArrayBlockingQueue;

public class Test {
    public static void main(String[] args) {
      //抛出异常
    test1();
    }
    public static void test1(){
        //队列的大小
        //Exception in thread "main" java.lang.IllegalStateException: Queue full
        // System.out.println(blockingQueue.add("d"));
        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("===============================");
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        //队列中只有三个值,但是移除了四次,则会抛出异常
        //Exception in thread "main" java.util.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"));
    System.out.println("============================");
    System.out.println(blockingQueue.poll());
    System.out.println(blockingQueue.poll());
    System.out.println(blockingQueue.poll());
    System.out.println(blockingQueue.poll());
}

超过队列中的最大容量会返回false:
在这里插入图片描述
队列中没有元素了,但还是选择弹出,会返回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("========================");
​        System.out.println(blockingQueue.take());
​        System.out.println(blockingQueue.take());
​        System.out.println(blockingQueue.take());
​        System.out.println(blockingQueue.take());}/**

   * 等待,阻塞(一直阻塞)

     ​     *

   * 等待,阻塞(等待超时)
     /

}

如果容量为3放了4个,会一直阻塞队列
在这里插入图片描述
只要三个,取了4次.会一直阻塞队列
在这里插入图片描述
4.超时等待

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));
}

最后一个值因为没等到,超时后直接返回空
在这里插入图片描述
完整代码:

package com.Blockqueue;

import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

public class Test {
    public static void main(String[] args) throws InterruptedException {
      //抛出异常
    test4();
    }
    public static void test1(){
        //队列的大小
        //Exception in thread "main" java.lang.IllegalStateException: Queue full
        // System.out.println(blockingQueue.add("d"));
        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.element());
        System.out.println("===============================");
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        //队列中只有三个值,但是移除了四次,则会抛出异常
        //Exception in thread "main" java.util.NoSuchElementException}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"));
​        System.out.println("============================");
​        System.out.println(blockingQueue.poll());
​        System.out.println(blockingQueue.poll());
​        System.out.println(blockingQueue.poll());
​        System.out.println(blockingQueue.poll());}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("========================");
​        System.out.println(blockingQueue.take());
​        System.out.println(blockingQueue.take());
​        System.out.println(blockingQueue.take());
​        System.out.println(blockingQueue.take());}/**

   * 等待,阻塞(一直阻塞)

     ​     *

   * 等待,阻塞(等待超时)
     /
     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));
     }

}

SynchronousQueue:同步队列

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

package com;

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

/**

 * 同步队列
 * 和其他的BlockingQueue不一样,synchronizequeue不存储元素
 * put了一个元素,必须从里面先take出来才能继续放,否则不能再put进去值
 * 如果连续put三个值进去就只进去一个值,其他值进不去,进而阻塞队列
   */
   public class SynchronousQueueDemo01 {
   public static void main(String[] args) throws InterruptedException {
       BlockingQueue<String> blockingqueue = new SynchronousQueue<>();//同步队列
       new Thread(()->{
           try {
               System.out.println(Thread.currentThread().getName()+":put 1");
               blockingqueue.put("1");
               System.out.println(Thread.currentThread().getName()+":put 2");
               blockingqueue.put("2");
               System.out.println(Thread.currentThread().getName()+":put 3");
               blockingqueue.put("3");
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       },Thread.currentThread().getName()).start();
       new Thread(()->{
           try {
               TimeUnit.SECONDS.sleep(3);
               System.out.println(Thread.currentThread().getName()+"取出了"+blockingqueue.take());
               TimeUnit.SECONDS.sleep(3);
               System.out.println(Thread.currentThread().getName()+"取出了"+blockingqueue.take());
               TimeUnit.SECONDS.sleep(3);
               System.out.println(Thread.currentThread().getName()+"取出了"+blockingqueue.take());
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
       }).start();}
}

在这里插入图片描述

原创文章 32 获赞 52 访问量 638

猜你喜欢

转载自blog.csdn.net/qq_42400763/article/details/105827365