多线程阻塞队列

阻塞队列

FIFO: first in put first out put 先进先出

在这里插入图片描述
阻塞队列:含义如上的图两种情况

在这里插入图片描述
在这里插入图片描述

BlockingQueue 不是新的东西
什么情况下我们会使用阻塞队列:多线程并发处理,线程池!
IDEA 类关系图:
在这里插入图片描述

学会使用队列

这里面就两个操作:添加,移除

*四组Api

方式抛出异常有返回值,不抛出异常阻塞 等待超时等待
添加addoffer()put()offer( ,,)
移除removepoll ()take()poll( ,)
判断队列的首部elementpeek
  1. 抛出异常
  2. 不会抛出异常
  3. 阻塞等待
  4. 超时等待

四种情况代码案例:

package com.bq;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

public class Test {


    public static void main(String[] args) throws InterruptedException {
        //Collection
        //List
        //Set
        //BlockingQueue 不是新的东西

        //Test.test1();
        //Test.test2();
        //Test.test3();
        Test.test4();

    }


    /**
     * 第一组api 抛出异常
     */
    public static void test1(){

        //入参:默认的队列大小为3
        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("======================================");
        //我想再添加一个元素,结果抛出异常 java.lang.IllegalStateException: Queue full
       // System.out.println(blockingQueue.add("d"));
        //先进先出,正常弹出,移除元素 a
        System.out.println(blockingQueue.remove());
        //移除a 后在检测队首是哪个元素
        System.out.println(blockingQueue.element());
        System.out.println(blockingQueue.remove());
        System.out.println(blockingQueue.remove());
        //已经是空的,如果我再取数据,也会抛出异常 java.util.NoSuchElementException
      //  System.out.println(blockingQueue.remove());
    }


    /**
     *
     * 有返回值,没有异常
     */
    public static void test2(){

        //入参默认队列的大小为3,这种不抛出异常的用offer 方法
        ArrayBlockingQueue<Object> 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.peek());
        //因为默认初始化大小3,所有在假如第4个值得时候,不像上面add 方法一样抛出异常,现在返回为 false!
        System.out.println(blockingQueue.offer("d"));
        System.out.println("===================================================");
        //将所有的数据弹出来
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        //这个是返回null 不抛出异常了!
        System.out.println(blockingQueue.poll());
    }


    /**
     *
     * 等待,阻塞(一直阻塞)
     */
    public static void test3() throws InterruptedException {

        //入参默认队列的大小为3,这种一直阻塞的就用put 方法
        ArrayBlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(3);
        //put 方法是没有返回值的
        blockingQueue.put("a");
        blockingQueue.put("b");
        blockingQueue.put("c");
        //队列没有位置了,添加d 元素会处于一直等待状态
        //blockingQueue.put("d");

        //取值
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        System.out.println(blockingQueue.take());
        //上面已经取出3个元素了,如果我再取一次会出现什么了
        //如果这么操作则一直会等待这个操作,代码就死在这个地方了,一直阻塞!
        System.out.println(blockingQueue.take());
    }



    /**
     *
     * 等待,阻塞(等待超时)
     */
    public static void test4() throws InterruptedException {

        //队列的大小
        ArrayBlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<>(3);
        blockingQueue.offer("a");
        blockingQueue.offer("b");
        blockingQueue.offer("c");
        //假设再增加(d元素,超时时间,超时时间单位)
        //等待2 s 要时还是没有位置让我插入,等待超过2s 就退出!
        blockingQueue.offer("d",2,TimeUnit.SECONDS);
        System.out.println("==============");
        //取出值了
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        System.out.println(blockingQueue.poll());
        //等待超过2 秒就退出
        blockingQueue.poll(2,TimeUnit.SECONDS);
    }
}

同步队列SynchronousQueue

没有容量
进去一个元素,必须等待取出来知乎,才能再往里面放一个元素!
put,take

package com.bq;

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

/**
 * 同步队列
 * 与其他的BlockQueue 不一样,SynchronousQueue 不存储元素
 * 只要在里面put 一个元素,必须从里面take 取出来,否则不能在put 进去值!
 */
public class SynchronousQueueDemo {


    public static void main(String[] args) {
        BlockingQueue<String> blockingQueue = new SynchronousQueue<String>();
        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();
            }
        },"T1").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();
            }
        },"T2").start();
    }
}

输出结果:
T1=put 1
T2=>1
T1=put 2
T2=>2
T1=put 3
T2=>3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值