Java多线程学习之阻塞队列BlockingQueue

一、概述

BlockingQueue在java.util.concurrent包

首先是是一个队列,其实在多线程环境下自动阻塞或唤醒

BlockingQueue 具有 4 组不同的方法用于插入、移除以及对队列中的元素进行检查。如果请求的操作不能得到立即执行的话,每个方法的表现也不同。这些方法如下:

抛出异常特殊值阻塞超时
插入add(e)offer(e)put(e)offer(e, time, unit)
移除remove()poll()take()poll(time, unit)
检查element()peek()不可用不可用
 

四组不同的行为方式解释:

1(异常)

如果试图的操作无法立即执行,抛一个异常。

2(特定值) 

如果试图的操作无法立即执行,返回一个特定的值(常常是 true / false)。

3(阻塞) 

如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行。

4(超时) 

如果试图的操作无法立即执行,该方法调用将会发生阻塞,直到能够执行,但等待时间不会超过给定值。返回一个特定值以告知该操作是否成功(典型的是 true / false)。

二、测试代码

生产者/消费者

package com.example.blockingQueue;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Run {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("main start");

        BlockingQueue queue = new ArrayBlockingQueue(2);
        Producer producer = new Producer(queue);
        producer.start();

        Thread.sleep(5000);

        Consumer consumer = new Consumer(queue);
        consumer.start();
        System.out.println("main ok");
    }
}

/**
 * 消息生产者
 */
class Producer extends Thread {

    private int count = 1;
    private BlockingQueue queue;

    public Producer(BlockingQueue queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            while (true) {
                Thread.sleep(500);
                String message = "hello" + count++;
                queue.add(message);//抛出异常
                System.out.println(TimeUtils.getCurrentTime() + "生产者:开始,message:" + message + ",queue:" + queue.size());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


/**
 * 消息消费者
 */
class Consumer extends Thread {
    private BlockingQueue queue;

    public Consumer(BlockingQueue queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            while (true) {
                System.out.println(TimeUtils.getCurrentTime() + "消费者:" + queue.take());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class TimeUtils {
    public static String getCurrentTime() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss S").format(new Date());
    }
}

运行结果:

queue.add(message);//抛出异常

main start
2022-01-19 23:53:32 850生产者:开始,message:hello1,queue:1
2022-01-19 23:53:33 351生产者:开始,message:hello2,queue:2
java.lang.IllegalStateException: Queue full
    at java.util.AbstractQueue.add(AbstractQueue.java:98)
    at java.util.concurrent.ArrayBlockingQueue.add(ArrayBlockingQueue.java:312)
    at com.example.blockingQueue.Producer.run(Run.java:42)
main ok
2022-01-19 23:53:37 313消费者:hello1
2022-01-19 23:53:37 314消费者:hello2

修改代码

queue.put("hello"+ count);//阻塞

运行结果

main start
2022-01-20 00:11:29 112生产者:开始,message:hello1,queue:1
2022-01-20 00:11:29 613生产者:开始,message:hello2,queue:2
main ok
2022-01-20 00:11:33 577消费者:hello2
2022-01-20 00:11:33 578生产者:开始,message:hello3,queue:2
2022-01-20 00:11:33 578消费者:hello3
2022-01-20 00:11:33 579消费者:hello4
2022-01-20 00:11:33 580消费者:hello5
2022-01-20 00:11:34 78生产者:开始,message:hello4,queue:0
2022-01-20 00:11:34 78消费者:hello6
2022-01-20 00:11:34 578生产者:开始,message:hello5,queue:0
2022-01-20 00:11:34 578消费者:hello7
2022-01-20 00:11:35 79生产者:开始,message:hello6,queue:0
2022-01-20 00:11:35 79消费者:hello8
2022-01-20 00:11:35 579生产者:开始,message:hello7,queue:0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值