欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【JUC】005-阻塞队列BlockingQueue、同步队列SynchronousQueue

程序员文章站 2022-05-04 21:13:31
...

目录

一、阻塞队列BlockingQueue

1、说明

2、阻塞队列

3、结构图

4、BlockingQueue的4组API

有返回值抛出异常代码演示:

有返回值不抛出异常代码演示:

阻塞等待:

超时等待:

二、同步队列SynchronousQueue

1、概述

2、代码演示

代码实现:

运行结果:


一、阻塞队列BlockingQueue

1、说明

(不得不阻塞)

写入:如果队列满了,就必须阻塞等待;

读取:如果队列是空的,就必须阻塞等待;

 

2、阻塞队列

【JUC】005-阻塞队列BlockingQueue、同步队列SynchronousQueue

 

3、结构图

【JUC】005-阻塞队列BlockingQueue、同步队列SynchronousQueue

 

4、BlockingQueue的4组API

【JUC】005-阻塞队列BlockingQueue、同步队列SynchronousQueue

有返回值抛出异常代码演示:

    //有返回值抛出异常代码演示
    @Test
    public void test01(){
        //队列的大小
        ArrayBlockingQueue<Object> queue = new ArrayBlockingQueue<>(3);

        System.out.println(queue.add("a"));
        System.out.println(queue.add("b"));
        System.out.println(queue.add("c"));
        //此时队列满了,再添加则会抛出异常:java.lang.IllegalStateException: Queue full
//        System.out.println(queue.add("d"));

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

        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        //此时队列空了,再移除则会抛出异常:java.util.NoSuchElementException
//        System.out.println(queue.remove());
    }

有返回值不抛出异常代码演示:

    //有返回值不抛出异常代码演示
    @Test
    public void test02(){
        //队列的大小
        ArrayBlockingQueue<Object> queue = new ArrayBlockingQueue<>(3);

        System.out.println(queue.offer("a"));
        System.out.println(queue.offer("b"));
        System.out.println(queue.offer("c"));
        //此时队列满了,返回false,不抛出异常
        System.out.println(queue.offer("d"));

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

        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        //此时队列空了,返回null,不抛出异常
        System.out.println(queue.poll());
    }

阻塞等待:

    //阻塞等待
    @Test
    public void test03() throws InterruptedException {
        //队列的大小
        ArrayBlockingQueue<Object> queue = new ArrayBlockingQueue<>(3);

        queue.put("a");
        queue.put("b");
        queue.put("c");
        //此时队列满了,阻塞等待
//        queue.put("d");

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

        System.out.println(queue.take());
        System.out.println(queue.take());
        System.out.println(queue.take());
        //此时队列空了,阻塞等待
//        System.out.println(queue.take());
    }

超时等待:

    //超时等待
    @Test
    public void test04() throws InterruptedException {
        //队列的大小
        ArrayBlockingQueue<Object> queue = new ArrayBlockingQueue<>(3);

        queue.offer("a");
        queue.offer("b");
        queue.offer("c");
        //此时队列满了,超时等待
        queue.offer("d",2, TimeUnit.SECONDS);//等待超过两秒就退出

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

        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        //此时队列空了,超时等待
        System.out.println(queue.poll(2,TimeUnit.SECONDS));//等待超过两秒就退出

    }

 

二、同步队列SynchronousQueue

1、概述

存放一个元素,必须等待取出之后才能存放下一个元素;

 

2、代码演示

代码实现:

package com.zibo.sq;

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

//同步队列
public class TestSynchronousQueue {
    public static void main(String[] args) {
        SynchronousQueue<Object> queue = new SynchronousQueue<>();
        //存线程
        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName() + "put1");
                queue.put("1");
                System.out.println(Thread.currentThread().getName() + "put2");
                queue.put("2");
                System.out.println(Thread.currentThread().getName() + "put3");
                queue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"put线程").start();
        //取线程
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread().getName() + queue.take());
                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread().getName() + queue.take());
                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread().getName() + queue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"take线程").start();
    }
}

运行结果:

存1-取1-存2-取2-存3-取3

put线程put1
take线程1
put线程put2
take线程2
put线程put3
take线程3