阻塞队列(多线程)

阻塞队列是带有阻塞功能且线程安全的队列.(即,队列为空,尝试出队列,出队列操作就会阻塞等待一直阻塞到队列不为空为止,队列为满,入队操作就会阻塞等待一直阻塞到队列不满为止.) 阻塞队列的作用之一就是可以实现生产者消费者模型,有两方面的作用1.能够让程序解耦合 2.能够实现"削峰填谷".

首先使用标准库提供的阻塞队列.

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Demo1 {
    public static void main(String[] args){
        BlockingQueue<Integer> queue=new ArrayBlockingQueue<>(10);
        //消费者
        //put带有阻塞功能的入队列  take带有阻塞功能的出队列
        Thread t1=new Thread(()->{
            while(true) {
                int value;
                try {
                    value = queue.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("消费的:" + value);

            }
        });
        Thread t2=new Thread(()-> {
            int count=1;
            while (true) {
                try {
                    queue.put(count);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("生产的:"+count);
                count++;
            }
        });
        t1.start();
        t2.start();
    }
}
//由于对生产和消费没有限制虽然限制了队列的大小是10,所以没有体现出阻塞功能.

import java.sql.SQLOutput;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Demo2 {
    public static void main(String[] args){
        BlockingQueue<Integer> queue=new ArrayBlockingQueue<>(10);
        //生产者
        Thread t1=new Thread(()->{
            int count=1;
            while(true){
                try {
                    queue.put(count);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("生产者:"+count);
                count++;
            }
            //如果对消费者的速度进行限制,那么会使阻塞队列满

        });
        //消费者
        Thread t2=new Thread(()->{
            int value;
            while(true){
                try {
                    value=queue.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("消费者:"+value);
            }
        });
        //这里消费者是一秒钟消费一次,因此在进行出队列的时候会发生阻塞
        //且队列中只有10个元素.
        t1.start();
        t2.start();
    }
}

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Demo3 {
    public static void main(String[] args){
        BlockingQueue<Integer> queue=new ArrayBlockingQueue<>(10);
        Thread t1=new Thread(()->{
            int count=1;
           while(true) {
               try {
                   queue.put(count);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               System.out.println("生产者:"+ count);
               count++;
           }
        });
        Thread t2=new Thread(()->{
            int value;
            while(true){
                try {
                    value=queue.take();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("消费者:"+value);
            }
        });
        //这一次是没有对生产者进行限制,因此消费者的节奏会跟着生产者.
        t1.start();
        t2.start();
    }
}

接下来自己实现一个带有阻塞功能的队列.

//自己实现阻塞队列
class MyblockingQueue{
    //自己实现阻塞队列
    //设置一个队列是存储整形的
    private int[] elems=null;
    //[head,tail)
    //head是头结点,tail是尾结点
    //开始的时候,头结点和尾结点都是0,size也是0
    private int head=0;
    private int tail=0;
    private int size=0;
    //构造方法
    public MyblockingQueue(int capacity){
        elems=new int[capacity];
    }
    //下面写入队列操作
    void put(int elem) throws InterruptedException {
        //首先要判断队列是否满
        synchronized(this) {
            while (size >= elems.length) {
                this.wait();
                //如果队列满了就要进行阻塞操作
                //一定要进行返回等待,等待出队列操作的执行
                return;
            }
            //队列没有满入队列时
            //尾结点指向的空间没有存储元素
            elems[tail] = elem;
            tail++;
            if (tail >= elems.length) {
                tail = 0;
                //到达了队列的末尾就要回到开头
            }
            size++;
            this.notify();
        }
    }
  //出队列操作
    int take() throws InterruptedException {
        synchronized(this) {
            //还是要先判断队列是否是空,如果为空,就要阻塞等待
            while (size == 0) {
                this.wait();
                return -99999;
            }
            //出队列操作
            int result = elems[head];
            head++;
            if (head >= elems.length) {
                head = 0;
            }
            size--;
            this.notify();
            return result;
        }
    }
}
public class Demo2 {
    public static void main(String[] args) {
        MyblockingQueue tt=new MyblockingQueue(10);
        Thread t1=new Thread(()->{
            int count=0;
           while(true){
               try {
                   tt.put(count);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               System.out.println("生产者: "+count);
               count++;
           }
        });
        Thread t2=new Thread(()->{
           int value;
           while(true){
               try {
                   value=tt.take();
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
               System.out.println("消费者: "+value);
           }
        });
        t1.start();
        t2.start();
    }

}
相关推荐
好悬给我拽开线4 分钟前
【知识点】python whl安装与源码安装
开发语言·python
南七澄江4 分钟前
python爬虫:从12306网站获取火车站信息
开发语言·爬虫·python
哟哟-6 分钟前
python多线程开发
开发语言·前端·python
JSON_L14 分钟前
PHP 递归遍历目录
开发语言·后端·php
2401_8582861116 分钟前
E33.【C语言】数据在内存中的存储练习集(未完)
c语言·开发语言
ajax_beijing_java17 分钟前
记录一次排查sql server 服务调用异常的问题
java·服务器·数据库
蜡笔小新星18 分钟前
MySQL联合查询
数据库·经验分享·mysql
JavaGuide18 分钟前
面试官:谈谈你对 IoC 和 AOP 的理解!
java·spring·ioc·aop
2401_8576009523 分钟前
Spring Boot在心理辅导领域的创新应用
java·spring boot·后端
Li_03040624 分钟前
Servlet入门:服务端小程序的初试(自己学习整理的资料)
java·学习·servlet